home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume8 / jove / part05 < prev    next >
Encoding:
Internet Message Format  |  1987-02-02  |  58.2 KB

  1. Subject:  v08i024:  The JOVE text editor, Part05/13
  2. Newsgroups: mod.sources
  3. Approved: mirror!rs
  4.  
  5. Submitted by: seismo!rochester!jpayne (Jonathan Payne)
  6. Mod.sources: Volume 8, Issue 24
  7. Archive-name: jove/Part05
  8.  
  9. #! /bin/sh
  10. # This is a shell archive.  Remove anything before this line,
  11. # then unpack it by saving it in a file and typing "sh file".
  12. # If all goes well, you will see the message "End of archive 5 (of 13)."
  13. # Contents:  jove.c jove.h macros.c malloc.c marks.c setmaps.c
  14. PATH=/bin:/usr/bin:/usr/ucb; export PATH
  15. echo shar: extracting "'jove.c'" '(19628 characters)'
  16. if test -f 'jove.c' ; then 
  17.   echo shar: will not over-write existing file "'jove.c'"
  18. else
  19. sed 's/^X//' >jove.c <<'@//E*O*F jove.c//'
  20. X/************************************************************************
  21. X * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
  22. X * provided to you without charge, and with no warranty.  You may give  *
  23. X * away copies of JOVE, including sources, provided that this notice is *
  24. X * included in all the files.                                           *
  25. X ************************************************************************/
  26. X
  27. X/* Contains the main loop initializations, and some system dependent
  28. X   type things, e.g. putting terminal in CBREAK mode, etc. */
  29. X
  30. X#include "jove.h"
  31. X#include "io.h"
  32. X#include "termcap.h"
  33. X
  34. X#include <varargs.h>
  35. X#include <sys/stat.h>
  36. X#include <signal.h>
  37. X#include <errno.h>
  38. X#ifndef SYSV
  39. X#include <sgtty.h>
  40. X#else
  41. X#include <termio.h>
  42. X#endif SYSV
  43. X#include <fcntl.h>
  44. X
  45. X#ifdef TIOCSLTC
  46. Xstruct ltchars    ls1,
  47. X        ls2;
  48. X#endif TIOCSLTC
  49. X
  50. X#ifdef TIOCGETC
  51. Xstruct tchars    tc1,
  52. X        tc2;
  53. X#endif
  54. X
  55. X#ifdef BRLUNIX
  56. Xstruct sg_brl    sg1, sg2;
  57. X#else
  58. X#ifdef SYSV
  59. Xstruct termio    sg1, sg2;
  60. X#else SYSV
  61. Xstruct sgttyb    sg1, sg2;
  62. X#endif SYSV
  63. X#endif BRLUNIX
  64. X
  65. X#ifdef BIFF
  66. Xprivate struct stat    tt_stat;    /* for biff */
  67. X#ifndef BSD4_2
  68. Xprivate char    *tt_name = 0;        /* name of the control tty */
  69. Xextern char    *ttyname();        /* for systems w/o fchmod ... */
  70. X#endif
  71. Xprivate int    dw_biff = NO;        /* whether or not to fotz at all */
  72. X#endif
  73. X
  74. Xtime_t    time0;            /* when jove started up */
  75. Xint    errormsg;
  76. Xextern char    *tfname;
  77. Xchar    NullStr[] = "";
  78. X
  79. Xfinish(code)
  80. X{
  81. X    int    CoreDump = (code != 0 && code != SIGHUP),
  82. X        DelTmps = 1;        /* Usually we delete them. */
  83. X
  84. X#ifdef LSRHS
  85. X    if (CoreDump)
  86. X        setdump(1);
  87. X#endif
  88. X    if (code == SIGINT) {
  89. X        char    c;
  90. X
  91. X#ifndef MENLO_JCL
  92. X        (void) signal(code, finish);
  93. X#endif
  94. X        f_mess("Abort (Type 'n' if you're not sure)? ");
  95. X        (void) read(0, &c, 1);
  96. X        message(NullStr);
  97. X        if ((c & 0377) != 'y') {
  98. X            redisplay();
  99. X            return;
  100. X        }
  101. X    }
  102. X    ttyset(OFF);
  103. X    UnsetTerm(NullStr);
  104. X    if (code != 0) {
  105. X        if (!Crashing) {
  106. X            Crashing++;
  107. X            lsave();
  108. X            SyncRec();
  109. X            printf("JOVE CRASH!! (code %d)\n", code);
  110. X            if (ModBufs(1)) {
  111. X                printf("Your buffers have been saved.\n");
  112. X                printf("Use \"jove_recover\" or \"jove -r\"\n");
  113. X                printf("to have a look at them.\n");
  114. X                DelTmps = 0;    /* Don't delete anymore. */
  115. X            } else
  116. X                printf("You didn't lose any work.\n");
  117. X        } else
  118. X            printf("\r\nYou may have lost your work!\n");
  119. X    }
  120. X    flusho();
  121. X    if (DelTmps) {
  122. X        tmpclose();
  123. X        recclose();
  124. X    }
  125. X    if (CoreDump)
  126. X        abort();
  127. X#ifdef PROFILING
  128. X    exit(exp_p);
  129. X#else
  130. X    _exit(exp_p);
  131. X#endif
  132. X}
  133. X
  134. Xprivate char    smbuf[20],
  135. X        *bp = smbuf;
  136. Xprivate int    nchars = 0;
  137. X
  138. Xprivate char    peekbuf[10],
  139. X        *peekp = peekbuf;
  140. X
  141. X#ifdef SYSV
  142. Xvoid
  143. Xsetblock(fd, on)    /* turn blocking on or off */
  144. Xregister int    fd, on;
  145. X{
  146. X    static int blockf, nonblockf;
  147. X    static int first = 1;
  148. X    int flags;
  149. X
  150. X    if (first) {
  151. X    first = 0;
  152. X    if ((flags = fcntl(fd, F_GETFL, 0)) == -1)
  153. X        finish(SIGHUP);
  154. X    blockf = flags & ~O_NDELAY;    /* make sure O_NDELAY is off */
  155. X    nonblockf = flags | O_NDELAY;    /* make sure O_NDELAY is on */
  156. X    }
  157. X    if (fcntl(fd, F_SETFL, on ? blockf : nonblockf) == -1)
  158. X    finish(SIGHUP);
  159. X    return;
  160. X}
  161. X#endif SYSV
  162. X
  163. XPeekc()
  164. X{
  165. X    int    c;
  166. X
  167. X    if (peekp == peekbuf)
  168. X        c = -1;
  169. X    else
  170. X        c = *--peekp & 0377;
  171. X    return c;
  172. X}
  173. X
  174. XUngetc(c)
  175. X{
  176. X    if (peekp == &peekbuf[(sizeof peekbuf) - 1])
  177. X        return;        /* Sorry, can't oblige you ... */
  178. X    *peekp++ = c;
  179. X}
  180. X
  181. Xchar    *Inputp = 0;
  182. X
  183. X#ifdef IPROCS
  184. X#ifdef PIPEPROCS
  185. Xgetchar()
  186. X{
  187. X    extern int    errno;
  188. X    register int    c;
  189. X
  190. X    if (nchars <= 0) {
  191. X        do
  192. X            nchars = read(0, smbuf, sizeof smbuf);
  193. X#ifdef SYSV
  194. X        while (nchars == 0 || (nchars < 0 && errno == EINTR));
  195. X        if (nchars < 0)
  196. X#else
  197. X        while (nchars < 0 && errno == EINTR);
  198. X        if (nchars <= 0)
  199. X#endif SYSV
  200. X            finish(SIGHUP);
  201. X        bp = smbuf;
  202. X        InputPending = nchars > 1;
  203. X    }
  204. X    if (((c = *bp) & 0200) && MetaKey != 0) {
  205. X        *bp = (c & 0177);
  206. X        return '\033';
  207. X    }
  208. X    nchars--;
  209. X    return (*bp++ & 0177);
  210. X}
  211. X#else PIPEPROCS
  212. Xgetchar()
  213. X{
  214. X    extern int    global_fd,
  215. X            NumProcs,
  216. X            errno;
  217. X    register int    tmp,
  218. X            nfds;
  219. X    int    reads,
  220. X        c;
  221. X
  222. X    if (nchars <= 0) {
  223. X        /* Get a character from the keyboard, first checking for
  224. X           any input from a process.  Handle that first, and then
  225. X           deal with the terminal input. */
  226. X        if (NumProcs > 0) {
  227. X            do {
  228. X                do {
  229. X                    reads = global_fd;
  230. X                    nfds = select(32, &reads, (int *) 0, (int *) 0, (struct timeval *) 0);
  231. X                } while (nfds < 0 && errno == EINTR);
  232. X
  233. X                switch (nfds) {
  234. X                case -1:
  235. X                    printf("\rerror %d in select %d", errno, global_fd);
  236. X                    global_fd = 1;
  237. X                    break;
  238. X                default:
  239. X                    if (reads & 01) {
  240. X                        nchars = read(0, smbuf, sizeof(smbuf));
  241. X                        reads &= ~01;
  242. X                        --nfds;
  243. X                    }
  244. X
  245. X                    while (nfds--) {
  246. X                        tmp = ffs(reads) - 1;
  247. X                        read_proc(tmp);
  248. X                        reads &= ~tmp;
  249. X                    }
  250. X
  251. X                    break;
  252. X                }
  253. X            } while (nchars <= 0);
  254. X        } else {
  255. X            do
  256. X                nchars = read(0, smbuf, sizeof(smbuf));
  257. X            while (nchars < 0 && errno == EINTR);
  258. X        }
  259. X
  260. X        if (nchars <= 0)
  261. X            finish(SIGHUP);
  262. X
  263. X        bp = smbuf;
  264. X        InputPending = (nchars > 1);
  265. X    }
  266. X
  267. X    if (((c = *bp) & 0200) && MetaKey != 0) {
  268. X        *bp = (c & 0177);
  269. X        return '\033';
  270. X    }
  271. X    nchars--;
  272. X    return *bp++ & 0377;
  273. X}
  274. X#endif PIPEPROCS
  275. X#else IPROCS
  276. Xgetchar()
  277. X{
  278. X    extern int    errno;
  279. X    register int    c;
  280. X
  281. X    if (nchars <= 0) {
  282. X        do
  283. X            nchars = read(0, smbuf, sizeof smbuf);
  284. X        while (nchars < 0 && errno == EINTR);
  285. X
  286. X        if (nchars <= 0)
  287. X            finish(SIGHUP);
  288. X        bp = smbuf;
  289. X        InputPending = nchars > 1;
  290. X    }
  291. X    if (((c = *bp) & 0200) && MetaKey != 0) {
  292. X        *bp = (c & 0177);
  293. X        return '\033';
  294. X    }
  295. X    nchars--;
  296. X    return *bp++ & 0377;
  297. X}
  298. X#endif IPROCS
  299. X
  300. Xint    InputPending = 0;
  301. X
  302. X/* Returns non-zero if a character waiting */
  303. X
  304. Xcharp()
  305. X{
  306. X    int    some = 0;
  307. X
  308. X    if (InJoverc != 0 || nchars > 0 || Inputp != 0)
  309. X        return 1;
  310. X#ifdef BRLUNIX
  311. X    {
  312. X        static struct sg_brl gttyBuf;
  313. X
  314. X        gtty(0, (char *) >tyBuf);
  315. X        if (gttyBuf.sg_xflags & INWAIT)
  316. X            some++;
  317. X    }
  318. X#endif
  319. X#ifdef FIONREAD
  320. X    {
  321. X        long c;
  322. X
  323. X        if (ioctl(0, FIONREAD, (struct sgttyb *) &c) == -1)
  324. X            c = 0;
  325. X        some = (c > 0);
  326. X    }
  327. X#endif FIONREAD
  328. X#ifdef SYSV
  329. X    setblock(0, 0);        /* turn blocking off */
  330. X    nchars = read(0, smbuf, sizeof smbuf);    /* Is anything there? */
  331. X    setblock(0, 1);        /* turn blocking on */
  332. X    if (nchars > 0)        /* something was there */
  333. X        bp = smbuf;        /* make sure bp points to it */
  334. X    some = (nchars > 0);    /* just say we found something */
  335. X#endif SYSV
  336. X#ifdef c70
  337. X    some = !empty(0);
  338. X#endif
  339. X    return some;
  340. X}
  341. X
  342. XResetTerm()
  343. X{
  344. X    putpad(TI, 1);
  345. X    putpad(VS, 1);
  346. X    putpad(KS, 1);
  347. X#ifdef BIFF
  348. X    if (BiffChk != dw_biff)
  349. X        biff_init();
  350. X    /* just in case we changed our minds about whether to deal with
  351. X       biff */
  352. X#endif
  353. X    (void) chkmail(YES);    /* force it to check to we can be accurate */
  354. X    do_sgtty();        /* this is so if you change baudrate or stuff
  355. X                   like that, JOVE will notice. */
  356. X    ttyset(ON);
  357. X}
  358. X
  359. XUnsetTerm(mesg)
  360. Xchar    *mesg;
  361. X{
  362. X    ttyset(OFF);
  363. X    putpad(KE, 1);
  364. X    putpad(VE, 1);
  365. X    putpad(TE, 1);
  366. X#ifdef ID_CHAR
  367. X    INSmode(0);
  368. X#endif
  369. X    Placur(ILI, 0);
  370. X    printf("%s", mesg);
  371. X    putpad(CE, 1);
  372. X    flusho();
  373. X}
  374. X
  375. X#ifdef JOB_CONTROL
  376. XPauseJove()
  377. X{
  378. X    UnsetTerm(ModBufs(0) ? "[There are modified buffers]" : NullStr);
  379. X    (void) kill(0, SIGTSTP);
  380. X    ResetTerm();
  381. X    ClAndRedraw();
  382. X}
  383. X#endif
  384. X
  385. XPush()
  386. X{
  387. X    int    pid,
  388. X            (*old_int)() = signal(SIGINT, SIG_IGN),
  389. X        (*old_quit)() = signal(SIGQUIT, SIG_IGN);
  390. X
  391. X#ifdef IPROCS
  392. X    sighold(SIGCHLD);
  393. X#endif
  394. X    switch (pid = fork()) {
  395. X    case -1:
  396. X        complain("[Fork failed]");
  397. X
  398. X    case 0:
  399. X        UnsetTerm(NullStr);
  400. X#ifdef IPROCS
  401. X        sigrelse(SIGCHLD);
  402. X#endif
  403. X        (void) signal(SIGTERM, SIG_DFL);
  404. X        (void) signal(SIGINT, SIG_DFL);
  405. X        (void) signal(SIGQUIT, SIG_DFL);
  406. X        execl(Shell, basename(Shell), (char *)0);
  407. X        message("[Execl failed]");
  408. X        _exit(1);
  409. X    }
  410. X        dowait(pid, (int *) 0);
  411. X#ifdef IPROCS
  412. X    sigrelse(SIGCHLD);
  413. X#endif
  414. X        ResetTerm();
  415. X        ClAndRedraw();
  416. X    (void) signal(SIGQUIT, old_quit);
  417. X        (void) signal(SIGINT, old_int);
  418. X}
  419. X
  420. Xint    OKXonXoff = 0,        /* ^S and ^Q initially DON'T work */
  421. X    IntChar = CTL(]);
  422. X
  423. Xttsize()
  424. X{
  425. X#ifdef TIOCGWINSZ
  426. X    struct winsize win;
  427. X
  428. X    if (ioctl (0, TIOCGWINSZ, &win) == 0) {
  429. X        if (win.ws_col)
  430. X            CO = win.ws_col;
  431. X        if (win.ws_row)
  432. X            LI = win.ws_row;
  433. X    }
  434. X#else TIOCGWINSZ
  435. X#ifdef BTL_BLIT
  436. X#include <sys/jioctl.h>
  437. X    struct jwinsize jwin;
  438. X
  439. X    if (ioctl(0, JWINSIZE, &jwin) == 0) {
  440. X        if (jwin.bytesx)
  441. X            CO = jwin.bytesx;
  442. X        if (jwin.bytesy)
  443. X            LI = jwin.bytesy;
  444. X    }
  445. X#endif BTL_BLIT
  446. X#endif TIOCGWINSZ
  447. X    ILI = LI - 1;
  448. X}
  449. X
  450. X#ifdef BIFF
  451. Xbiff_init()
  452. X{
  453. X    dw_biff = ((BiffChk) &&
  454. X#ifndef BSD4_2
  455. X           ((tt_name != 0) || (tt_name = ttyname(0))) &&
  456. X           (stat(tt_name, &tt_stat) != -1) &&
  457. X#else
  458. X           (fstat(0, &tt_stat) != -1) &&
  459. X#endif
  460. X           (tt_stat.st_mode & S_IEXEC));    /* he's using biff */
  461. X
  462. X}
  463. X
  464. Xbiff(on)
  465. X{
  466. X    if (dw_biff == NO)
  467. X        return;
  468. X#ifndef BSD4_2
  469. X    (void) chmod(tt_name, on ? tt_stat.st_mode :
  470. X                   (tt_stat.st_mode & ~S_IEXEC));
  471. X#else
  472. X    (void) fchmod(0, on ? tt_stat.st_mode :
  473. X                  (tt_stat.st_mode & ~S_IEXEC));
  474. X#endif
  475. X}
  476. X
  477. X#endif
  478. X
  479. Xttinit()
  480. X{
  481. X#ifdef BIFF
  482. X    biff_init();
  483. X#endif
  484. X#ifdef TIOCSLTC
  485. X    (void) ioctl(0, TIOCGLTC, (struct sgttyb *) &ls1);
  486. X    ls2 = ls1;
  487. X    ls2.t_suspc = (char) -1;
  488. X    ls2.t_dsuspc = (char) -1;
  489. X    ls2.t_flushc = (char) -1;
  490. X    ls2.t_lnextc = (char) -1;
  491. X#endif
  492. X
  493. X#ifdef TIOCGETC
  494. X    /* Change interupt and quit. */
  495. X    (void) ioctl(0, TIOCGETC, (struct sgttyb *) &tc1);
  496. X    tc2 = tc1;
  497. X    tc2.t_intrc = IntChar;
  498. X    tc2.t_quitc = (char) -1;
  499. X    if (OKXonXoff) {
  500. X        tc2.t_stopc = (char) -1;
  501. X        tc2.t_startc = (char) -1;
  502. X    }
  503. X#endif TIOCGETC
  504. X    do_sgtty();
  505. X}
  506. X
  507. Xprivate int    done_ttinit = 0;
  508. X
  509. Xdo_sgtty()
  510. X{
  511. X#ifdef SYSV
  512. X    (void) ioctl(0, TCGETA, (char *) &sg1);
  513. X#else
  514. X    (void) gtty(0, &sg1);
  515. X#endif SYSV
  516. X    sg2 = sg1;
  517. X
  518. X#ifdef SYSV
  519. X    TABS = !((sg1.c_oflag & TAB3) == TAB3);
  520. X    ospeed = sg1.c_cflag & CBAUD;
  521. X
  522. X    sg2.c_iflag &= ~(INLCR|ICRNL|IGNCR);
  523. X    sg2.c_lflag &= ~(ISIG|ICANON|ECHO);
  524. X    sg2.c_oflag &= ~(OCRNL|ONLCR);
  525. X    sg2.c_cc[VMIN] = sizeof smbuf;
  526. X    sg2.c_cc[VTIME] = 1;
  527. X#else
  528. X    TABS = !(sg1.sg_flags & XTABS);
  529. X    ospeed = sg1.sg_ospeed;
  530. X#ifdef BRLUNIX
  531. X    sg2.sg_flags &= ~(ECHO | CRMOD);
  532. X    sg2.sg_flags |= CBREAK;
  533. X
  534. X    /* VT100 Kludge: leave STALL on for flow control if DC3DC1 (Yuck.) */
  535. X    sg2.sg_xflags &= ~((sg2.sg_xflags&DC3DC1 ? 0 : STALL) | PAGE);
  536. X#else
  537. X    sg2.sg_flags &= ~(ECHO | CRMOD);
  538. X#endif BRLUNIX
  539. X
  540. X#ifdef EUNICE
  541. X    sg2.sg_flags |= RAW;    /* Eunice needs RAW mode last I heard. */
  542. X#else
  543. X#ifdef PURDUE_EE
  544. X#   ifdef pdp11
  545. X    sg2.sg_flags |= RAW;
  546. X#   else
  547. X    sg2.sg_flags |= (MetaKey ? RAW : CBREAK);
  548. X#   endif
  549. X#else
  550. X    sg2.sg_flags |= (MetaKey ? RAW : CBREAK);
  551. X#endif PURDUE_EE
  552. X#endif EUNICE
  553. X#endif SYSV
  554. X}
  555. X
  556. Xtty_reset()
  557. X{
  558. X    if (!done_ttinit)
  559. X        return;
  560. X    ttyset(OFF);    /* go back to original modes */
  561. X    ttinit();
  562. X    ttyset(ON);
  563. X}
  564. X
  565. X/* If n is OFF reset to original modes */
  566. X
  567. Xttyset(n)
  568. X{
  569. X    if (!done_ttinit && n == 0)    /* Try to reset before we've set! */
  570. X        return;
  571. X#ifdef SYSV
  572. X    (void) ioctl(0, TCSETAW, n == 0 ? (struct sgttyb *) &sg1 : (struct sgttyb *) &sg2);
  573. X#else
  574. X#ifdef BRLUNIX
  575. X    (void) stty(0, n == 0 ? (struct sgttyb *) &sg1 : (struct sgttyb *) &sg2);
  576. X#else
  577. X    (void) ioctl(0, TIOCSETN, n == 0 ? (struct sgttyb *) &sg1 : (struct sgttyb *) &sg2);
  578. X#endif BRLUNIX
  579. X#endif SYSV
  580. X
  581. X#ifdef TIOCSETC
  582. X    (void) ioctl(0, TIOCSETC, n == 0 ? (struct sgttyb *) &tc1 : (struct sgttyb *) &tc2);
  583. X#endif TIOCSETC
  584. X#ifdef TIOCSLTC
  585. X    (void) ioctl(0, TIOCSLTC, n == 0 ? (struct sgttyb *) &ls1 : (struct sgttyb *) &ls2);
  586. X#endif TIOCSLTC
  587. X    done_ttinit = 1;
  588. X#ifdef BIFF
  589. X    biff(!n);
  590. X#endif
  591. X}
  592. X
  593. Xint    this_cmd,
  594. X    last_cmd;
  595. X
  596. Xdispatch(c)
  597. Xregister int    c;
  598. X{
  599. X    data_obj    *cp;
  600. X
  601. X    this_cmd = 0;
  602. X    cp = mainmap[c & 0177];
  603. X
  604. X    if (cp == 0) {
  605. X        rbell();
  606. X        exp = 1;
  607. X        exp_p = errormsg = NO;
  608. X        message(NullStr);
  609. X    } else
  610. X        ExecCmd(cp);
  611. X}
  612. X
  613. Xint    LastKeyStruck,
  614. X    MetaKey = 0;
  615. X
  616. Xgetch()
  617. X{
  618. X    register int    c,
  619. X            peekc;
  620. X#ifdef IPROCS
  621. X    extern int    NumProcs;
  622. X#endif
  623. X    extern int    ModCount,
  624. X            Interactive;
  625. X
  626. X    if (Inputp) {
  627. X        if ((c = *Inputp++) != 0)
  628. X            return LastKeyStruck = c;
  629. X        Inputp = 0;
  630. X    }
  631. X
  632. X    if (InJoverc)
  633. X        return EOF;    /* somethings wrong if Inputp runs out while
  634. X                   we're reading a .joverc file. */
  635. X
  636. X    if (ModCount >= SyncFreq) {
  637. X        ModCount = 0;
  638. X        SyncRec();
  639. X    }
  640. X
  641. X    /* If we're not interactive and we're not executing a macro,
  642. X       AND there are no ungetc'd characters, we read from the
  643. X       terminal (i.e., getch()).  And characters only get put
  644. X       in macros from inside this if. */
  645. X    if (((peekc = c = Peekc()) == -1) && (Interactive || ((c = mac_getc()) == -1))) {
  646. X        /* So messages that aren't error messages don't
  647. X           hang around forever. */
  648. X        if (!UpdMesg && !Asking) {    /* Don't erase if we are asking */
  649. X            if (mesgbuf[0] && !errormsg)
  650. X                message(NullStr);
  651. X        }
  652. X        redisplay();
  653. X#ifdef IPROCS
  654. X#  ifdef PIPEPROCS
  655. X        if (NumProcs > 0) {
  656. X            sigrelse(INPUT_SIG);
  657. X            sigrelse(SIGCHLD);
  658. X        }
  659. X#  endif
  660. X#endif
  661. X        inIOread = 1;
  662. X        if ((c = getchar()) == EOF)
  663. X            finish(SIGHUP);
  664. X        inIOread = 0;
  665. X
  666. X#ifdef IPROCS
  667. X#  ifdef PIPEPROCS
  668. X        if (NumProcs > 0) {
  669. X            sighold(INPUT_SIG);
  670. X            sighold(SIGCHLD);
  671. X        }
  672. X#  endif
  673. X#endif
  674. X        if (!Interactive && (KeyMacro.m_flags & DEFINE))
  675. X            mac_putc(c);
  676. X    }
  677. X    if (peekc == -1)    /* Don't add_stroke peekc's */
  678. X        add_stroke(c);
  679. X    return LastKeyStruck = c;
  680. X}
  681. X
  682. Xdorecover()
  683. X{
  684. X    execl(Recover, "jove_recover", "-d", TmpFilePath, (char *)0);
  685. X    printf("%s: execl failed!\n", Recover);
  686. X    flusho();
  687. X    _exit(-1);
  688. X}
  689. X        
  690. X
  691. XShowVersion()
  692. X{
  693. X    extern char    *version;
  694. X
  695. X    s_mess("Jonathan's Own Version of Emacs (%s)", version);
  696. X}
  697. X
  698. XUNIX_cmdline(argc, argv)
  699. Xchar    *argv[];
  700. X{
  701. X    int    lineno = 0,
  702. X        nwinds = 1;
  703. X    Buffer    *b;
  704. X
  705. X    ShowVersion();
  706. X    while (argc > 1) {
  707. X        if (argv[1][0] != '-' && argv[1][0] != '+') {
  708. X            int    force = (nwinds > 0 || lineno != 0);
  709. X
  710. X            minib_add(argv[1], force ? YES : NO);
  711. X            b = do_find(nwinds > 0 ? curwind : (Window *) 0,
  712. X                    argv[1], force);
  713. X            if (force) {
  714. X                SetABuf(curbuf);
  715. X                SetBuf(b);
  716. X                SetLine(next_line(curbuf->b_first, lineno));
  717. X                if (nwinds > 1)
  718. X                    NextWindow();
  719. X                if (nwinds)
  720. X                    nwinds--;
  721. X            }
  722. X            lineno = 0;
  723. X        } else    switch (argv[1][1]) {
  724. X            case 'd':
  725. X                ++argv;
  726. X                --argc;
  727. X                break;
  728. X
  729. X            case 'j':    /* Ignore .joverc in HOME */
  730. X                break;
  731. X
  732. X            case 'p':
  733. X                ++argv;
  734. X                --argc;
  735. X                SetBuf(do_find(curwind, argv[1], 0));
  736. X                ParseAll();
  737. X                nwinds = 0;
  738. X                break;
  739. X
  740. X            case 't':
  741. X                ++argv;
  742. X                --argc;
  743. X                exp_p = YES;
  744. X                find_tag(argv[1], YES);
  745. X                break;
  746. X
  747. X            case 'w':
  748. X                if (argv[1][2] == '\0')
  749. X                    nwinds++;
  750. X                else
  751. X                    nwinds += -1 + chr_to_int(&argv[1][2], 10, NIL);
  752. X                (void) div_wind(curwind, nwinds - 1);
  753. X                break;
  754. X
  755. X            case '0':
  756. X            case '1':
  757. X            case '2':
  758. X            case '3':
  759. X            case '4':
  760. X            case '5':
  761. X            case '6':
  762. X            case '7':
  763. X            case '8':
  764. X            case '9':
  765. X                lineno = chr_to_int(&argv[1][1], 10, 0) - 1;
  766. X                break;
  767. X        }
  768. X        ++argv;
  769. X        --argc;
  770. X    }
  771. X}
  772. X
  773. X/* VARARGS1 */
  774. X
  775. Xerror(fmt, va_alist)
  776. Xchar    *fmt;
  777. Xva_dcl
  778. X{
  779. X    va_list    ap;
  780. X
  781. X    if (fmt) {
  782. X        va_start(ap);
  783. X        format(mesgbuf, sizeof mesgbuf, fmt, ap);
  784. X        va_end(ap);
  785. X        UpdMesg++;
  786. X    }
  787. X    rbell();
  788. X    (void) longjmp(mainjmp, ERROR);
  789. X}
  790. X
  791. X/* VARARGS1 */
  792. X
  793. Xcomplain(fmt, va_alist)
  794. Xchar    *fmt;
  795. Xva_dcl
  796. X{
  797. X    va_list    ap;
  798. X
  799. X    if (fmt) {
  800. X        va_start(ap);
  801. X        format(mesgbuf, sizeof mesgbuf, fmt, ap);
  802. X        va_end(ap);
  803. X        UpdMesg++;
  804. X    }
  805. X    rbell();
  806. X    (void) longjmp(mainjmp, COMPLAIN);
  807. X}
  808. X
  809. X/* VARARGS1 */
  810. X
  811. Xconfirm(fmt, va_alist)
  812. Xchar    *fmt;
  813. Xva_dcl
  814. X{
  815. X    char    *yorn;
  816. X    va_list    ap;
  817. X
  818. X    va_start(ap);
  819. X    format(mesgbuf, sizeof mesgbuf, fmt, ap);
  820. X    va_end(ap);
  821. X    yorn = ask((char *) 0, mesgbuf);
  822. X    if (*yorn != 'Y' && *yorn != 'y')
  823. X        (void) longjmp(mainjmp, COMPLAIN);
  824. X}
  825. X
  826. Xint    RecDepth = 0;
  827. X
  828. XRecur()
  829. X{
  830. X    char    bname[128];
  831. X    Mark    *m;
  832. X
  833. X    sprintf(bname, "%s", curbuf->b_name);
  834. X    m = MakeMark(curline, curchar, FLOATER);
  835. X
  836. X    RecDepth++;
  837. X    UpdModLine++;
  838. X    DoKeys(1);    /* 1 means not first time */
  839. X    UpdModLine++;
  840. X    RecDepth--;
  841. X    SetBuf(do_select(curwind, bname));
  842. X    if (exp_p == NO)
  843. X        ToMark(m);
  844. X    DelMark(m);
  845. X}
  846. X
  847. Xjmp_buf    mainjmp;
  848. Xint    iniargc;    /* main sets these for DoKeys() */
  849. Xchar    **iniargv;
  850. X
  851. XDoKeys(nocmdline)
  852. X{
  853. X    int    c;
  854. X    jmp_buf    savejmp;
  855. X
  856. X    push_env(savejmp);
  857. X
  858. X    switch (setjmp(mainjmp)) {
  859. X    case 0:
  860. X        if (!nocmdline)
  861. X            UNIX_cmdline(iniargc, iniargv);
  862. X        break;
  863. X
  864. X    case QUIT:
  865. X        if (RecDepth == 0) {
  866. X            if (ModMacs()) {
  867. X                rbell();
  868. X                if (Upper(*ask("No",
  869. X"Some MACROS haven't been saved; leave anyway? ")) != 'Y')
  870. X                    break;
  871. X            }
  872. X            if (ModBufs(0)) {
  873. X                rbell();
  874. X                if (Upper(*ask("No",
  875. X"Some buffers haven't been saved; leave anyway? ")) != 'Y')
  876. X                    break;
  877. X            }
  878. X#ifdef IPROCS
  879. X            KillProcs();
  880. X#endif
  881. X        }
  882. X        pop_env(savejmp);
  883. X        return;
  884. X
  885. X    case ERROR:
  886. X        getDOT();    /* God knows what state linebuf was in */
  887. X
  888. X    case COMPLAIN:
  889. X        gc_openfiles();    /* close any files we left open */
  890. X        errormsg++;
  891. X        fix_macros();
  892. X        Asking = 0;
  893. X        curwind->w_bufp = curbuf;
  894. X        redisplay();
  895. X        break;
  896. X    }
  897. X
  898. X    this_cmd = last_cmd = 0;
  899. X
  900. X    for (;;) {
  901. X        if (this_cmd != ARG_CMD) {
  902. X            exp = 1;
  903. X            exp_p = NO;
  904. X            last_cmd = this_cmd;
  905. X            init_strokes();
  906. X        }
  907. X        c = getch();
  908. X        if (c == -1)
  909. X            continue;
  910. X         dispatch(c);
  911. X    }
  912. X}
  913. X
  914. Xint    Crashing = 0;
  915. X
  916. Xchar **
  917. Xscanvec(args, str)
  918. Xregister char    **args,
  919. X        *str;
  920. X{
  921. X    while (*args) {
  922. X        if (strcmp(*args, str) == 0)
  923. X            return args;
  924. X        args++;
  925. X    }
  926. X    return 0;
  927. X}
  928. X
  929. Xint    UpdFreq = 30,
  930. X    inIOread = 0;
  931. X
  932. Xupdmode()
  933. X{
  934. X    UpdModLine++;
  935. X    if (inIOread)
  936. X        redisplay();
  937. X#ifndef JOB_CONTROL
  938. X    (void) signal(SIGALRM, updmode);
  939. X#endif
  940. X    (void) alarm((unsigned) UpdFreq);
  941. X}
  942. X
  943. X#ifdef TIOCGWINSZ
  944. X#ifdef SIGWINCH
  945. Xextern win_reshape();
  946. X#endif
  947. X#endif
  948. X
  949. X#ifdef TIOCGWINSZ
  950. X#ifdef SIGWINCH
  951. Xwin_reshape()
  952. X{
  953. X    register int diff;
  954. X
  955. X    (void) signal(SIGWINCH, SIG_IGN);
  956. X
  957. X    /*
  958. X     * Save old number of lines.
  959. X     */
  960. X    diff = LI;
  961. X
  962. X    /*
  963. X     * Get new line/col info.
  964. X     */
  965. X    ttsize();
  966. X
  967. X    /*
  968. X     * LI has changed, and now holds the
  969. X     * new value.  See how much the size
  970. X     * changed.
  971. X     */
  972. X    diff = LI - diff;
  973. X
  974. X    /*
  975. X     * Change the size of the current window
  976. X     * only.  If they shrank by more than
  977. X     * the window size, tough.
  978. X     */
  979. X    if ((curwind->w_height + diff) < 2)
  980. X        curwind->w_height = 2;
  981. X    else
  982. X        curwind->w_height += diff;
  983. X
  984. X    make_scr();
  985. X    redisplay();
  986. X
  987. X    (void) signal(SIGWINCH, win_reshape);
  988. X}
  989. X#endif
  990. X#endif
  991. X
  992. Xmain(argc, argv)
  993. Xchar    *argv[];
  994. X{
  995. X    char    ttbuf[512],
  996. X#ifndef VMUNIX
  997. X        s_iobuff[LBSIZE],
  998. X        s_genbuf[LBSIZE],
  999. X        s_linebuf[LBSIZE],
  1000. X#endif
  1001. X        *cp;
  1002. X
  1003. X
  1004. X#ifndef VMUNIX
  1005. X    /* The way I look at it, there ain't no way I is gonna run
  1006. X       out of stack space UNLESS I have some kind of infinite
  1007. X       recursive bug.  So why use up some valuable memory, when
  1008. X       there is plenty of space on the stack?  (This only matters
  1009. X       on wimpy pdp11's, of course.) */
  1010. X
  1011. X    iobuff = s_iobuff;
  1012. X    genbuf = s_genbuf;
  1013. X    linebuf = s_linebuf;
  1014. X#endif
  1015. X
  1016. X    errormsg = 0;
  1017. X
  1018. X    iniargc = argc;
  1019. X    iniargv = argv;
  1020. X
  1021. X    if (setjmp(mainjmp)) {
  1022. X        printf("\rAck! I can't deal with error \"%s\" now.\n\r", mesgbuf);
  1023. X        finish(0);
  1024. X    }
  1025. X
  1026. X    getTERM();    /* Get terminal. */
  1027. X    if (getenv("METAKEY"))
  1028. X        MetaKey = 1;
  1029. X    ttsize();
  1030. X    InitCM();
  1031. X
  1032. X    d_cache_init();        /* initialize the disk buffer cache */
  1033. X
  1034. X    if (cp = getenv("SHELL"))
  1035. X        strcpy(Shell, cp);
  1036. X
  1037. X    make_scr();
  1038. X    mac_init();    /* Initialize Macros */
  1039. X    winit();    /* Initialize Window */
  1040. X#ifdef IPROCS
  1041. X    pinit();    /* Pipes/process initialization */
  1042. X#endif
  1043. X    SetBuf(do_select(curwind, Mainbuf));
  1044. X
  1045. X#ifdef CHDIR
  1046. X    {
  1047. X        char    **argp;
  1048. X
  1049. X        if ((argp = scanvec(argv, "-d")) && (argp[1][0] == '/'))
  1050. X            setCWD(argp[1]);
  1051. X        else
  1052. X            getCWD();    /* After we setup curbuf in case we have to getwd() */
  1053. X    }
  1054. X#endif
  1055. X    HomeDir = getenv("HOME");
  1056. X    if (HomeDir == 0)
  1057. X        HomeDir = "/";
  1058. X    HomeLen = strlen(HomeDir);
  1059. X#ifdef SYSV
  1060. X    sprintf(Mailbox, "/usr/mail/%s", getenv("LOGNAME"));
  1061. X#else
  1062. X    sprintf(Mailbox, "/usr/spool/mail/%s", getenv("USER"));
  1063. X#endif SYSV
  1064. X    (void) joverc(Joverc);
  1065. X    if (!scanvec(argv, "-j")) {
  1066. X        char    tmpbuf[100];
  1067. X
  1068. X        sprintf(tmpbuf, "%s/.joverc", HomeDir);
  1069. X        (void) joverc(tmpbuf);
  1070. X    }
  1071. X    if (scanvec(argv, "-r"))
  1072. X        dorecover();
  1073. X
  1074. X    (void) time(&time0);
  1075. X    ttinit();    /* initialize terminal (after ~/.joverc) */
  1076. X    settout(ttbuf);    /* not until we know baudrate */
  1077. X    ResetTerm();
  1078. X
  1079. X    (void) signal(SIGHUP, finish);
  1080. X    (void) signal(SIGINT, finish);
  1081. X    (void) signal(SIGBUS, finish);
  1082. X    (void) signal(SIGSEGV, finish);
  1083. X    (void) signal(SIGPIPE, finish);
  1084. X    (void) signal(SIGTERM, SIG_IGN);
  1085. X#ifdef TIOCGWINSZ
  1086. X#ifdef SIGWINCH
  1087. X    (void) signal(SIGWINCH, win_reshape);
  1088. X#endif
  1089. X#endif
  1090. X
  1091. X    /* set things up to update the modeline every UpdFreq seconds */
  1092. X    (void) signal(SIGALRM, updmode);
  1093. X    (void) alarm((unsigned) UpdFreq);
  1094. X
  1095. X    cl_scr(1);
  1096. X    flusho();
  1097. X    RedrawDisplay();    /* start the redisplay process. */
  1098. X    DoKeys(0);
  1099. X    finish(0);
  1100. X}
  1101. @//E*O*F jove.c//
  1102. if test 19628 -ne "`wc -c <'jove.c'`"; then
  1103.     echo shar: error transmitting "'jove.c'" '(should have been 19628 characters)'
  1104. fi
  1105. fi # end of overwriting check
  1106. echo shar: extracting "'jove.h'" '(14747 characters)'
  1107. if test -f 'jove.h' ; then 
  1108.   echo shar: will not over-write existing file "'jove.h'"
  1109. else
  1110. sed 's/^X//' >jove.h <<'@//E*O*F jove.h//'
  1111. X/************************************************************************
  1112. X * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
  1113. X * provided to you without charge, and with no warranty.  You may give  *
  1114. X * away copies of JOVE, including sources, provided that this notice is *
  1115. X * included in all the files.                                           *
  1116. X ************************************************************************/
  1117. X
  1118. X/* jove.h header file to be included by EVERYONE */
  1119. X
  1120. X#include <setjmp.h>
  1121. X#include <sys/types.h>
  1122. X
  1123. X#ifndef TUNED
  1124. X#   include "tune.h"
  1125. X#endif
  1126. X
  1127. X#define private    static
  1128. X
  1129. X#ifndef BSD4_2
  1130. X#   ifdef MENLO_JCL
  1131. X#    ifndef EUNICE
  1132. X#        define signal    sigset
  1133. X#    endif
  1134. X#   endif MENLO_JCL
  1135. X#endif
  1136. X
  1137. X#define EOF    -1
  1138. X#define NULL    0
  1139. X#define NIL    0
  1140. X
  1141. X/* kinds of regular expression compiles */
  1142. X#define NORM    0    /* nothing special */
  1143. X#define OKAY_RE    1    /* allow regular expressions */
  1144. X#define IN_CB    2    /* in curly brace; implies OKAY_RE */
  1145. X
  1146. X/* return codes for command completion (all < 0 because >= 0 are
  1147. X   legitimate offsets into array of strings */
  1148. X
  1149. X#define AMBIGUOUS    -2    /* matches more than one at this point */
  1150. X#define UNIQUE        -3    /* matches only one string */
  1151. X#define ORIGINAL    -4    /* matches no strings at all! */
  1152. X#define NULLSTRING    -5    /* just hit return without typing anything */
  1153. X
  1154. X/* values for the `flags' argument to complete */
  1155. X#define NOTHING        0    /* opposite of RET_STATE */
  1156. X#define RET_STATE    1    /* return state when we hit return */
  1157. X#define RCOMMAND    2    /* we are reading a joverc file */
  1158. X#define CASEIND        4    /* map all to lower case */
  1159. X
  1160. X#define DEFINE        01    /* defining this macro */
  1161. X#define EXECUTE        02    /* executing this macro */
  1162. X#define SAVE        04    /* this macro needs saving to a file */
  1163. X
  1164. X#define    LBSIZE        BUFSIZ    /* same as a logical disk block */
  1165. X#define FILESIZE    256
  1166. X
  1167. X#define FORWARD        1
  1168. X#define BACKWARD    -1
  1169. X
  1170. X#define CTL(c)        ('c' & 037)
  1171. X#define META(c)        ('c' | 0200)
  1172. X#define RUBOUT        '\177'
  1173. X#define LF        CTL(J)
  1174. X#define CR        CTL(M)
  1175. X#define BS        CTL(H)
  1176. X#define ESC        '\033'
  1177. X
  1178. X#define DoTimes(f, n)    exp_p = YES, exp = n, f
  1179. X#define HALF(wp)    ((wp->w_height - 1) / 2)
  1180. X#define IsModified(b)    (b->b_modified)
  1181. X#define SIZE(wp)    (wp->w_height - 1)
  1182. X#define SavLine(a, b)    (a->l_dline = putline(b))
  1183. X#define SetLine(line)    DotTo(line, 0)
  1184. X#define bobp()        (firstp(curline) && bolp())
  1185. X#define bolp()        (curchar == 0)
  1186. X#define eobp()        (lastp(curline) && eolp())
  1187. X#define eolp()        (linebuf[curchar] == '\0')
  1188. X#define firstp(line)    (line == curbuf->b_first)
  1189. X#define getDOT()    getline(curline->l_dline, linebuf)
  1190. X#define isdirty(line)    (line->l_dline & DIRTY)
  1191. X#define lastp(line)    (line == curbuf->b_last)
  1192. X#define makedirty(line)    line->l_dline |= DIRTY
  1193. X#define one_windp()    (fwind->w_next == fwind)
  1194. X
  1195. Xextern int    OkayAbort,    /* okay to abort redisplay */
  1196. X        BufSize;
  1197. X
  1198. X#define ARG_CMD        1
  1199. X#define LINECMD        2
  1200. X#define KILLCMD        3    /* so we can merge kills */
  1201. X#define YANKCMD        4    /* so we can do ESC Y (yank-pop) */
  1202. X
  1203. X/* Buffer type */
  1204. X
  1205. X#define B_SCRATCH    1    /* for internal things, e.g. minibuffer ... */
  1206. X#define B_FILE        2    /* normal file (We Auto-save these.) */
  1207. X#define B_PROCESS    3    /* process output in this buffer */
  1208. X
  1209. X/* Major modes */
  1210. X#define FUNDAMENTAL    0    /* Fundamental mode */
  1211. X#define TEXT        1    /* Text mode */
  1212. X#define CMODE        2    /* C mode */
  1213. X#ifdef LISP
  1214. X#    define LISPMODE        3    /* Lisp mode */
  1215. X#    define NMAJORS        4
  1216. X#else
  1217. X#    define NMAJORS    3
  1218. X#endif
  1219. X
  1220. X/* Minor Modes */
  1221. X#define Indent        (1 << 0)    /* indent same as previous line after return */
  1222. X#define ShowMatch    (1 << 1)    /* paren flash mode */
  1223. X#define Fill        (1 << 2)    /* text fill mode */
  1224. X#define OverWrite    (1 << 3)    /* over write mode */
  1225. X#define Abbrev        (1 << 4)    /* abbrev mode */
  1226. X
  1227. X#define BufMinorMode(b, x)    (b->b_minor & x)
  1228. X
  1229. X#define MinorMode(x)    BufMinorMode(curbuf, x)
  1230. X#define MajorMode(x)    (curbuf->b_major == x)
  1231. X#define SetMajor(x)    ((curbuf->b_major = x), UpdModLine++)
  1232. X
  1233. Xextern char    CharTable[NMAJORS][128];
  1234. X
  1235. X/* setjmp/longjmp args for DoKeys() mainjmp */
  1236. X#define FIRSTCALL    0
  1237. X#define ERROR        1
  1238. X#define COMPLAIN    2    /* do the error without a getDOT */
  1239. X#define QUIT        3    /* leave this level of recursion */
  1240. X
  1241. X#define QUIET        1    /* sure, why not? */
  1242. X
  1243. X#define YES        1
  1244. X#define NO        0
  1245. X#define TRUE        1
  1246. X#define FALSE        0
  1247. X#define ON        1
  1248. X#define OFF        0
  1249. X#define YES_NODIGIT    2
  1250. X
  1251. Xextern char    *Mainbuf,
  1252. X        *HomeDir,    /* home directory */
  1253. X        key_strokes[],    /* strokes that make up current command */
  1254. X        *Inputp;
  1255. X
  1256. Xextern int    HomeLen;    /* length of home directory */
  1257. X
  1258. Xextern char    NullStr[];
  1259. X
  1260. X#ifdef VMUNIX
  1261. Xextern char    genbuf[LBSIZE],
  1262. X        linebuf[LBSIZE],
  1263. X        iobuff[LBSIZE];
  1264. X#else
  1265. Xextern char    *genbuf,    /* scratch pad points at s_genbuf (see main()) */
  1266. X        *linebuf,    /* points at s_linebuf */
  1267. X        *iobuff;    /* for file reading ... points at s_iobuff */
  1268. X#endif
  1269. X
  1270. Xextern int    InJoverc,
  1271. X        Interactive;
  1272. X
  1273. X#define    READ    0
  1274. X#define    WRITE    1
  1275. Xextern int    errno;
  1276. X
  1277. Xextern jmp_buf    mainjmp;
  1278. X
  1279. X#ifdef IPROCS
  1280. Xtypedef struct process    Process;
  1281. X#endif
  1282. Xtypedef struct window    Window;
  1283. Xtypedef struct position    Bufpos;
  1284. Xtypedef struct mark    Mark;
  1285. Xtypedef struct buffer    Buffer;
  1286. Xtypedef struct line    Line;
  1287. Xtypedef struct iobuf    IOBUF;
  1288. Xtypedef struct data_obj {
  1289. X    int    Type;
  1290. X    char    *Name;
  1291. X} data_obj;    /* points to cmd, macro, or variable */
  1292. Xtypedef data_obj    *keymap[0200];
  1293. X
  1294. Xstruct line {
  1295. X    Line    *l_prev,        /* pointer to prev */
  1296. X        *l_next;        /* pointer to next */
  1297. X    disk_line    l_dline;    /* pointer to disk location */
  1298. X};
  1299. X
  1300. X#ifdef IPROCS
  1301. Xstruct process {
  1302. X    Process    *p_next;
  1303. X#ifdef PIPEPROCS
  1304. X    int    p_toproc,    /* read p_fromproc and write p_toproc */
  1305. X        p_portpid,    /* Pid of child (the portsrv) */
  1306. X        p_pid;        /* Pid of real child i.e. not portsrv */
  1307. X#else
  1308. X    int    p_fd,        /* File descriptor of ptyp? opened r/w */
  1309. X        p_pid;        /* pid of child (the shell) */
  1310. X#endif
  1311. X    Buffer    *p_buffer;    /* Add output to end of this buffer */
  1312. X    char    *p_name;    /* ... */
  1313. X    char    p_state,    /* State */
  1314. X        p_howdied,    /* Killed? or Exited? */
  1315. X        p_reason,    /* If signaled, p_reason is the signal; else
  1316. X                   it is the the exit code */
  1317. X        p_eof;        /* Received EOF, so can be free'd up */
  1318. X    Mark    *p_mark;    /* Where output left us. */
  1319. X    data_obj
  1320. X        *p_cmd;        /* Command to call when process dies */
  1321. X};
  1322. X#endif IPROCS
  1323. X
  1324. Xstruct window {
  1325. X    Window    *w_prev,    /* circular list */
  1326. X        *w_next;
  1327. X    Buffer    *w_bufp;    /* buffer associated with this window */
  1328. X    Line    *w_top,        /* top line */
  1329. X        *w_line;    /* current line */
  1330. X    int    w_char,
  1331. X        w_height,    /* window height */
  1332. X        w_topnum,    /* line number of the topline */
  1333. X        w_dotcol,    /* UpdWindow sets this ... */
  1334. X        w_dotline,    /* ... and this */
  1335. X        w_flags;
  1336. X#define    W_TOPGONE    01
  1337. X#define    W_CURGONE    02    /* topline (curline) of window has been deleted
  1338. X                   since the last time a redisplay was called */
  1339. X#define W_VISSPACE    04
  1340. X#define W_NUMLINES    010
  1341. X};
  1342. X
  1343. Xextern Window    *fwind,        /* first window in list */
  1344. X        *curwind;    /* current window */
  1345. X
  1346. Xstruct position {
  1347. X    Line    *p_line;
  1348. X    int    p_char;
  1349. X};
  1350. X
  1351. Xstruct mark {
  1352. X    Line    *m_line;
  1353. X    int    m_char;
  1354. X    Mark    *m_next;    /* list of marks */
  1355. X#define FLOATER    1
  1356. X    char    m_floater;    /* FLOATERing mark? */
  1357. X};
  1358. X
  1359. Xstruct buffer {
  1360. X    Buffer    *b_next;        /* next buffer in chain */
  1361. X    char    *b_name,        /* buffer name */
  1362. X        *b_fname;        /* file name associated with buffer */
  1363. X    ino_t    b_ino;            /* inode of file name */
  1364. X    time_t    b_mtime;        /* last modify time ...
  1365. X                       to detect two people writing
  1366. X                       to the same file */
  1367. X    Line    *b_first,        /* pointer to first line in list */
  1368. X        *b_dot,            /* current line */
  1369. X        *b_last;        /* last line in list */
  1370. X    int    b_char;            /* current character in line */
  1371. X
  1372. X#define NMARKS    8            /* number of marks in the ring */
  1373. X
  1374. X    Mark    *b_markring[NMARKS],    /* new marks are pushed saved here */
  1375. X        *b_marks;        /* all the marks for this buffer */
  1376. X    char    b_themark,        /* current mark (in b_markring) */
  1377. X        b_type,            /* file, scratch, process, iprocess */
  1378. X        b_ntbf,            /* needs to be found when we
  1379. X                       first select? */
  1380. X        b_modified;        /* is the buffer modified? */
  1381. X    int    b_major,        /* major mode */
  1382. X        b_minor;        /* and minor mode */
  1383. X    keymap    *b_keybinds;        /* local bindings (if any) */
  1384. X#ifdef IPROCS
  1385. X    Process    *b_process;        /* process we're attached to */
  1386. X#endif
  1387. X};
  1388. X
  1389. Xstruct macro {
  1390. X    int    Type;        /* in this case a macro */
  1391. X    char    *Name;        /* name is always second ... */
  1392. X    int    m_len,        /* length of macro so we can use ^@ */
  1393. X        m_buflen,    /* memory allocated for it */
  1394. X        m_offset,    /* index into body for defining and running */
  1395. X        m_flags,    /* defining/running this macro? */
  1396. X        m_ntimes;    /* number of times to run this macro */
  1397. X    char    *m_body;    /* actual body of the macro */
  1398. X    struct macro
  1399. X        *m_nextm;
  1400. X};
  1401. X
  1402. Xstruct variable {
  1403. X    int    Type;        /* in this case a variable */
  1404. X    char    *Name;        /* name is always second */
  1405. X    int    *v_value,
  1406. X        v_flags;
  1407. X};
  1408. X
  1409. Xstruct cmd {
  1410. X    int    Type;
  1411. X    char    *Name;
  1412. X    int    (*c_proc)();
  1413. X};
  1414. X
  1415. Xextern keymap    mainmap,    /* various key maps */
  1416. X        pref1map,
  1417. X        pref2map,
  1418. X        miscmap;
  1419. X
  1420. Xextern data_obj    *LastCmd;    /* last command invoked */
  1421. X
  1422. Xextern char    *ProcFmt;
  1423. X
  1424. Xextern struct cmd    commands[];
  1425. Xextern struct macro    *macros;
  1426. Xextern struct variable    variables[];
  1427. X
  1428. Xextern struct macro
  1429. X    *macstack[],
  1430. X    KeyMacro;
  1431. X
  1432. X#define FUNCTION    1
  1433. X#define VARIABLE    2
  1434. X#define MACRO        3
  1435. X#define TYPEMASK    07
  1436. X#define MAJOR_MODE    010
  1437. X#define MINOR_MODE    020
  1438. X#define DefMajor(x)    (FUNCTION|MAJOR_MODE|(x << 8))
  1439. X#define DefMinor(x)    (FUNCTION|MINOR_MODE|(x << 8))
  1440. X
  1441. Xextern Buffer    *world,        /* first buffer */
  1442. X        *curbuf;    /* pointer into world for current buffer */
  1443. X
  1444. X#define curline    curbuf->b_dot
  1445. X#define curchar curbuf->b_char
  1446. X
  1447. X#define NUMKILLS    10    /* number of kills saved in the kill ring */
  1448. X
  1449. X#define DIRTY        01    /* just needs updating for some reason */
  1450. X#define MODELINE    02    /* this is a modeline */
  1451. X#define L_MOD        04    /* this line has been modified internally */
  1452. X
  1453. Xstruct scrimage {
  1454. X    int    s_offset,    /* offset to start printing at */
  1455. X        s_flags,    /* various flags */
  1456. X        s_id,        /* which buffer line */
  1457. X        s_vln;        /* Visible Line Number */
  1458. X    Line    *s_lp;        /* so we can turn off red bit */
  1459. X    Window    *s_window;    /* window that contains this line */
  1460. X};
  1461. X
  1462. Xextern struct scrimage
  1463. X    *DesiredScreen,        /* what we want */
  1464. X    *PhysScreen;        /* what we got */
  1465. X
  1466. X/* Variable flags (that can be set). */
  1467. X#define V_BASE10    01    /* is integer in base 10 */
  1468. X#define V_BASE8        02    /* is integer in base 8 */
  1469. X#define V_BOOL        04    /* is a boolean */
  1470. X#define V_STRING    010    /* is a string */
  1471. X#define V_CHAR        020    /* is a character */
  1472. X#define V_FILENAME    040    /* a file name (implies V_STRING) */
  1473. X#define V_TYPEMASK    077    /* mask off the extra bits */
  1474. X#define V_MODELINE    0100    /* update modeline */
  1475. X#define V_CLRSCREEN    0200    /* clear and redraw screen */
  1476. X#define V_TTY_RESET    0400    /* redo the tty modes */
  1477. X
  1478. Xextern int
  1479. X    OKXonXoff,        /* disable start/stop characters */
  1480. X    MetaKey,        /* this terminal has a meta key */
  1481. X    VisBell,        /* use visible bell (if possible) */
  1482. X    WrapScan,        /* make searches wrap */
  1483. X    phystab,        /* terminal's tabstop settings */ 
  1484. X    tabstop,        /* expand tabs to this number of spaces */
  1485. X#ifdef BACKUPFILES
  1486. X    BkupOnWrite,        /* make backup files when writing */
  1487. X#endif
  1488. X    RMargin,        /* right margin */
  1489. X    LMargin,        /* left margin */
  1490. X    ScrollStep,        /* how should we scroll */
  1491. X    WtOnMk,            /* write files on compile-it command */
  1492. X    EndWNewline,        /* end files with a blank line */
  1493. X    MarkThresh,        /* moves greater than MarkThresh
  1494. X                   will SetMark */
  1495. X    PDelay,            /* paren flash delay in tenths of a second */
  1496. X    CIndIncrmt,        /* how much each indentation level pushes
  1497. X                   over in C mode */
  1498. X    CreatMode,        /* default mode for creat'ing files */
  1499. X    CaseIgnore,        /* case ignore search */
  1500. X#ifdef ABBREV
  1501. X    AutoCaseAbbrev,        /* automatically do case on abbreviations */
  1502. X#endif
  1503. X    MarksShouldFloat,    /* adjust marks on insertion/deletion */
  1504. X    UseRE,            /* use regular expressions in search */
  1505. X    SyncFreq,        /* how often to sync the file pointers */
  1506. X    BriteMode,        /* make the mode line inverse? */
  1507. X    OkayBadChars,        /* allow bad characters in files created
  1508. X                   by JOVE */
  1509. X    UpdFreq,        /* how often to update modeline */
  1510. X    UseBuffers,        /* use buffers with Typeout() */
  1511. X#ifdef BIFF
  1512. X    BiffChk,        /* turn off/on biff with entering/exiting jove */
  1513. X#endif
  1514. X    MailInt,        /* mail check interval */
  1515. X#ifdef ID_CHAR
  1516. X    UseIC,            /* whether or not to use i/d char
  1517. X                   processesing */
  1518. X    SExitChar,        /* type this to stop i-search */
  1519. X#endif
  1520. X    IntChar,        /* ttysets this to generate QUIT */
  1521. X    EWSize;            /* size to make the error window */
  1522. X
  1523. Xextern char
  1524. X#ifdef IPROCS
  1525. X    proc_prompt[80],    /* process prompt */
  1526. X#endif
  1527. X#ifdef F_COMPLETION
  1528. X    BadExtensions[128],    /* extensions (e.g., ".o" to ignore) */
  1529. X#endif
  1530. X#ifdef CMT_FMT
  1531. X    CmtFmt[80],
  1532. X#endif
  1533. X    ModeFmt[120],        /* mode line format string */
  1534. X    Mailbox[128],        /* mailbox name */
  1535. X    TmpFilePath[128],    /* directory/device to store tmp files */
  1536. X    TagFile[128],        /* default tag file */
  1537. X    Shell[128];        /* shell to use */
  1538. X
  1539. Xextern int
  1540. X    exp,        /* argument count */
  1541. X    exp_p,        /* argument count is supplied */
  1542. X
  1543. X    TOabort,    /* flag set by Typeout() */
  1544. X    io,        /* file descriptor for reading and writing files */
  1545. X    errormsg,    /* last message was an error message
  1546. X               so don't erase the error before it
  1547. X               has been read */
  1548. X    this_cmd,    /* ... */
  1549. X    last_cmd,    /* last command ... to implement appending
  1550. X               to kill buffer */
  1551. X    RecDepth,    /* recursion depth */
  1552. X    InputPending,    /* nonzero if there is input waiting to
  1553. X               be processed */
  1554. X     killptr,    /* index into killbuf */
  1555. X    CanScroll,    /* can this terminal scroll? */
  1556. X    Crashing,    /* we are in the middle of crashing */
  1557. X    Asking,        /* are we on read a string from the terminal? */
  1558. X    inIOread;    /* so we know whether we can do a redisplay. */
  1559. X
  1560. Xextern char    Minibuf[LBSIZE];
  1561. X
  1562. X#define curmark        (curbuf->b_markring[curbuf->b_themark])
  1563. X#define b_curmark(b)    (b->b_markring[b->b_themark])
  1564. X
  1565. Xextern Line    *killbuf[NUMKILLS];    /* array of pointers to killed stuff */
  1566. X
  1567. X#define MESG_SIZE 128
  1568. Xextern char    mesgbuf[MESG_SIZE];
  1569. X
  1570. Xstruct screenline {
  1571. X    char    *s_line,
  1572. X        *s_length;
  1573. X};
  1574. X
  1575. Xextern int
  1576. X    LastKeyStruck;
  1577. X
  1578. Xextern int
  1579. X    stackp,
  1580. X
  1581. X    CapLine,    /* cursor line and cursor column */
  1582. X    CapCol,
  1583. X
  1584. X    UpdModLine,    /* whether we want to update the mode line */
  1585. X    UpdMesg;    /* update the message line */
  1586. X
  1587. X#define CATCH \
  1588. X{\
  1589. X    jmp_buf    sav_jmp; \
  1590. X\
  1591. X    push_env(sav_jmp); \
  1592. X    if (setjmp(mainjmp) == 0) {
  1593. X
  1594. X#define ONERROR \
  1595. X    } else { \
  1596. X
  1597. X#define ENDCATCH \
  1598. X    } \
  1599. X    pop_env(sav_jmp); \
  1600. X}
  1601. X
  1602. Xextern int
  1603. X    read(),
  1604. X    write();
  1605. X    getch();
  1606. X
  1607. Xextern time_t    time();
  1608. Xextern long    lseek();
  1609. X
  1610. Xextern disk_line
  1611. X    putline();
  1612. X
  1613. Xextern data_obj
  1614. X    *findcom(),
  1615. X    *findvar(),
  1616. X    *findmac();
  1617. X
  1618. Xextern Line
  1619. X    *next_line(),
  1620. X    *prev_line(),
  1621. X    *nbufline(),
  1622. X    *reg_delete(),
  1623. X    *lastline(),
  1624. X    *listput();
  1625. X
  1626. Xextern char
  1627. X    *getsearch(),
  1628. X    *pwd(),
  1629. X    *itoa(),
  1630. X    *get_time(),
  1631. X    *copystr(),
  1632. X    *basename(),
  1633. X    *filename(),
  1634. X    *IOerr(),
  1635. X    *index(),
  1636. X    *ask(),
  1637. X    *do_ask(),
  1638. X    *ask_buf(),
  1639. X    *ask_file(),
  1640. X    *lcontents(),
  1641. X    *malloc(),
  1642. X    *emalloc(),
  1643. X    *mktemp(),
  1644. X    *realloc(),
  1645. X    *ltobuf(),
  1646. X    *lbptr(),
  1647. X    *rindex(),
  1648. X    *getenv(),
  1649. X    *tgoto(),
  1650. X    *pr_name(),
  1651. X    *sprint(),
  1652. X    *StrIndex();
  1653. X
  1654. Xextern Bufpos
  1655. X    *docompiled(),
  1656. X    *dosearch(),
  1657. X    *DoYank(),
  1658. X    *c_indent(),
  1659. X#ifdef LISP
  1660. X    *lisp_indent(),
  1661. X#endif
  1662. X    *m_paren();
  1663. X
  1664. Xextern Mark
  1665. X    *CurMark(),
  1666. X    *MakeMark();
  1667. X
  1668. Xextern Window
  1669. X    *windbp(),
  1670. X    *div_wind();
  1671. X
  1672. Xextern data_obj
  1673. X    **IsPrefix();
  1674. X
  1675. Xextern Buffer
  1676. X    *do_find(),
  1677. X    *do_select(),
  1678. X    *mak_buf(),
  1679. X    *buf_exists(),
  1680. X    *file_exists();
  1681. X
  1682. Xstruct cmd *
  1683. X    FindCmd();
  1684. @//E*O*F jove.h//
  1685. if test 14747 -ne "`wc -c <'jove.h'`"; then
  1686.     echo shar: error transmitting "'jove.h'" '(should have been 14747 characters)'
  1687. fi
  1688. fi # end of overwriting check
  1689. echo shar: extracting "'macros.c'" '(9026 characters)'
  1690. if test -f 'macros.c' ; then 
  1691.   echo shar: will not over-write existing file "'macros.c'"
  1692. else
  1693. sed 's/^X//' >macros.c <<'@//E*O*F macros.c//'
  1694. X/************************************************************************
  1695. X * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
  1696. X * provided to you without charge, and with no warranty.  You may give  *
  1697. X * away copies of JOVE, including sources, provided that this notice is *
  1698. X * included in all the files.                                           *
  1699. X ************************************************************************/
  1700. X
  1701. X#include "jove.h"
  1702. X
  1703. Xstruct macro    *macros = 0;        /* Macros */
  1704. Xdata_obj    *LastCmd;
  1705. X
  1706. Xprivate
  1707. Xadd_mac(new)
  1708. Xstruct macro    *new;
  1709. X{
  1710. X    register struct macro    *mp,
  1711. X                *prev = 0;
  1712. X
  1713. X    for (mp = macros; mp != 0; prev = mp, mp = mp->m_nextm)
  1714. X        if (mp == new)
  1715. X            return;
  1716. X
  1717. X    if (prev)
  1718. X        prev->m_nextm = new;
  1719. X    else
  1720. X        macros = new;
  1721. X    new->m_nextm = 0;
  1722. X    new->Type = MACRO;
  1723. X}
  1724. X
  1725. Xprivate
  1726. Xdel_mac(mac)
  1727. Xstruct macro    *mac;
  1728. X{
  1729. X    register struct macro    *m;
  1730. X
  1731. X    for (m = macros; m != 0; m = m->m_nextm)
  1732. X        if (m->m_nextm == mac) {
  1733. X            m->m_nextm = mac->m_nextm;
  1734. X            break;
  1735. X        }
  1736. X    free(mac->Name);
  1737. X    free(mac->m_body);
  1738. X    free((char *) mac);
  1739. X}
  1740. X
  1741. Xstruct macro    KeyMacro;    /* Macro used for defining */
  1742. X
  1743. X#define NMACROS    40        /* This is bad, bad, BAD! */
  1744. X
  1745. Xstruct macro    *macstack[NMACROS];
  1746. Xprivate int    stackp = 0;
  1747. X
  1748. Xfix_macros()
  1749. X{
  1750. X    register int    i;
  1751. X    register struct macro    *mp;
  1752. X
  1753. X    for (i = 0; macstack[i]; i++) {
  1754. X        mp = macstack[i];
  1755. X        macstack[i] = 0;
  1756. X        mp->m_flags = mp->m_offset = 0;
  1757. X    }
  1758. X    stackp = -1;
  1759. X    KeyMacro.m_flags = KeyMacro.m_offset = 0;
  1760. X}
  1761. X
  1762. Xprivate
  1763. Xmac_err(err)
  1764. Xchar    *err;
  1765. X{
  1766. X    KeyMacro.m_flags = 0;
  1767. X    MacNolen(&KeyMacro);
  1768. X    complain(err);
  1769. X}
  1770. X
  1771. Xdo_macro(mac)
  1772. Xstruct macro    *mac;
  1773. X{
  1774. X    if (mac->m_flags & EXECUTE)
  1775. X        mac_err("[Attempt to execute macro recursively!]");
  1776. X    if (++stackp >= NMACROS)
  1777. X        complain("[Too many macros at once!]");
  1778. X    macstack[stackp] = mac;
  1779. X    mac->m_offset = 0;
  1780. X    mac->m_ntimes = exp;
  1781. X    mac->m_flags |= EXECUTE;
  1782. X}
  1783. X
  1784. Xprivate
  1785. XMacNolen(m)
  1786. Xstruct macro    *m;
  1787. X{
  1788. X    m->m_len = m->m_offset = 0;
  1789. X}
  1790. X
  1791. Xprivate struct macro *
  1792. Xmac_exists(name)
  1793. Xchar    *name;
  1794. X{
  1795. X    register struct macro    *mp;
  1796. X
  1797. X    for (mp = macros; mp; mp = mp->m_nextm)
  1798. X        if (strcmp(mp->Name, name) == 0)
  1799. X            return mp;
  1800. X    return 0;
  1801. X}
  1802. X
  1803. Xmac_init()
  1804. X{
  1805. X    add_mac(&KeyMacro);
  1806. X    MacNolen(&KeyMacro);
  1807. X    KeyMacro.Name = "keyboard-macro";
  1808. X    KeyMacro.m_buflen = 16;
  1809. X    KeyMacro.m_body = emalloc(KeyMacro.m_buflen);
  1810. X    KeyMacro.m_ntimes = KeyMacro.m_flags = 0;
  1811. X    fix_macros();
  1812. X}
  1813. X
  1814. Xmac_putc(c)
  1815. Xint    c;
  1816. X{
  1817. X    if (KeyMacro.m_len >= KeyMacro.m_buflen) {
  1818. X        KeyMacro.m_buflen += 16;
  1819. X        KeyMacro.m_body = realloc(KeyMacro.m_body, (unsigned) KeyMacro.m_buflen);
  1820. X        if (KeyMacro.m_body == 0)
  1821. X            mac_err("[Can't allocate storage for keyboard macro]");
  1822. X    }
  1823. X    KeyMacro.m_body[KeyMacro.m_offset++] = c;
  1824. X    KeyMacro.m_len++;
  1825. X}
  1826. X
  1827. Xin_macro()
  1828. X{
  1829. X    return ((stackp >= 0) && ((macstack[stackp])->m_flags & EXECUTE));
  1830. X}
  1831. X
  1832. Xmac_getc()
  1833. X{
  1834. X    struct macro    *m;
  1835. X
  1836. X    if (stackp < 0 || ((m = macstack[stackp])->m_flags & EXECUTE) == 0)
  1837. X        return -1;
  1838. X    if (m->m_offset == m->m_len) {
  1839. X        m->m_offset = 0;
  1840. X        if (--m->m_ntimes == 0) {
  1841. X            m->m_flags &= ~EXECUTE;
  1842. X            stackp--;
  1843. X        }
  1844. X        return mac_getc();
  1845. X    }
  1846. X    return m->m_body[m->m_offset++];
  1847. X}
  1848. X
  1849. XNameMac()
  1850. X{
  1851. X    char    *name;
  1852. X    struct macro    *m;
  1853. X
  1854. X    if (KeyMacro.m_len == 0)
  1855. X        complain("[No keyboard macro to name!]");
  1856. X    if (KeyMacro.m_flags & (DEFINE | EXECUTE))
  1857. X        complain("[Can't name while defining/executing]");
  1858. X    if ((m = mac_exists(name = ask((char *) 0, ProcFmt))) == 0)
  1859. X        m = (struct macro *) emalloc(sizeof *m);
  1860. X    else {
  1861. X        if (strcmp(name, KeyMacro.Name) == 0)
  1862. X            complain("[Can't name it that!]");
  1863. X        free(m->Name);
  1864. X        free(m->m_body);
  1865. X    }
  1866. X    name = copystr(name);
  1867. X    m->Type = KeyMacro.Type;
  1868. X    m->m_len = KeyMacro.m_len;
  1869. X    m->m_buflen = KeyMacro.m_buflen;
  1870. X    m->m_body = emalloc(m->m_buflen);
  1871. X    byte_copy(KeyMacro.m_body, m->m_body, m->m_len);
  1872. X    m->m_ntimes = m->m_offset = 0;    /* At the beginning */
  1873. X    m->m_flags = SAVE;
  1874. X    m->Name = name;
  1875. X    add_mac(m);
  1876. X}    
  1877. X
  1878. XRunMacro()
  1879. X{
  1880. X    struct macro    *m;
  1881. X
  1882. X    if (m = (struct macro *) findmac(ProcFmt))
  1883. X        do_macro(m);
  1884. X}
  1885. X
  1886. Xprivate int    mac_fd;
  1887. X
  1888. Xprivate
  1889. Xmac_io(fcn, ptr, nbytes)
  1890. Xint    (*fcn)();
  1891. Xchar    *ptr;
  1892. X{
  1893. X    int    nio;
  1894. X
  1895. X    if ((nio = (*fcn)(mac_fd, ptr, nbytes)) != nbytes)
  1896. X        complain("[Macro %s error: %d got %d]",
  1897. X             (fcn == read) ? "read" : "write",
  1898. X             nbytes,
  1899. X             nio);
  1900. X}
  1901. X
  1902. XWriteMacs()
  1903. X{
  1904. X    struct macro    *m;
  1905. X    int    namelen,
  1906. X        netl,
  1907. X        nmacs = 0;
  1908. X    char    *file,
  1909. X        filebuf[FILESIZE];
  1910. X    long htonl() ;
  1911. X
  1912. X    file = ask_file((char *) 0, (char *) 0, filebuf);
  1913. X    if ((mac_fd = creat(file, 0666)) == -1)
  1914. X        complain(IOerr("create", file));
  1915. X    f_mess("\"%s\"", file);
  1916. X
  1917. X    /* Don't write the keyboard macro which is always the first */
  1918. X    for (m = macros->m_nextm; m != 0; m = m->m_nextm) {
  1919. X        if (m->m_len == 0)
  1920. X            continue;
  1921. X        nmacs++;
  1922. X        netl = htonl(m->m_len);
  1923. X        mac_io(write, (char *) &netl, sizeof m->m_len);
  1924. X        namelen = strlen(m->Name) + 1;    /* Including the null */
  1925. X        netl = htonl(namelen);
  1926. X        mac_io(write, (char *) &netl, sizeof namelen);
  1927. X        mac_io(write, m->Name, namelen);
  1928. X        mac_io(write, m->m_body, m->m_len);
  1929. X        m->m_flags &= ~SAVE;
  1930. X    }
  1931. X    (void) close(mac_fd);
  1932. X    add_mess(" %d macro%n saved.", nmacs, nmacs);
  1933. X}
  1934. X
  1935. X#define NEWWAY    1
  1936. X#define OLDWAY    0
  1937. X
  1938. Xprivate int    int_how = NEWWAY;
  1939. X
  1940. X/* Formatting int's the old way or the new "improved" way? */
  1941. X
  1942. X#if vax || pdp11
  1943. Xlong htonl(x)
  1944. Xregister long x;
  1945. X{
  1946. X    return(    (((x >>  0) & 0377) << 24) |
  1947. X        (((x >>  8) & 0377) << 16) |
  1948. X        (((x >> 16) & 0377) <<  8) |
  1949. X        (((x >> 24) & 0377) <<  0) );
  1950. X}
  1951. X
  1952. Xshort htons(x)
  1953. Xregister short x;
  1954. X{
  1955. X    return(    (((x >>  0) & 0377) << 8) |
  1956. X        (((x >>  8) & 0377) << 0) );
  1957. X}
  1958. X
  1959. Xlong ntohl(x)
  1960. Xregister long x;
  1961. X{
  1962. X    return(    (((x >>  0) & 0377) << 24) |
  1963. X        (((x >>  8) & 0377) << 16) |
  1964. X        (((x >> 16) & 0377) <<  8) |
  1965. X        (((x >> 24) & 0377) <<  0) );
  1966. X}
  1967. X
  1968. Xshort ntohs(x)
  1969. Xregister short x;
  1970. X{
  1971. X    return(    (((x >>  0) & 0377) << 8) |
  1972. X        (((x >>  8) & 0377) << 0) );
  1973. X}
  1974. X#else
  1975. Xlong htonl(x)
  1976. Xregister long x;
  1977. X{
  1978. X    return(x);
  1979. X}
  1980. X
  1981. Xshort htons(x)
  1982. Xregister short x;
  1983. X{
  1984. X    return(x);
  1985. X}
  1986. X
  1987. Xlong ntohl(x)
  1988. Xregister long x;
  1989. X{
  1990. X    return(x);
  1991. X}
  1992. X
  1993. Xshort ntohs(x)
  1994. Xregister short x;
  1995. X{
  1996. X    return(x);
  1997. X}
  1998. X#endif
  1999. X
  2000. Xint_fmt(i)
  2001. X{
  2002. X    if (int_how == NEWWAY)
  2003. X        return ntohl(i);
  2004. X    return i;
  2005. X}
  2006. X
  2007. XReadMacs()
  2008. X{
  2009. X    char    *file,
  2010. X        filebuf[FILESIZE];
  2011. X    struct macro    *m;
  2012. X    int    nmacs = 0,
  2013. X        namelen,
  2014. X        bodylen,
  2015. X        tmp,
  2016. X        he_is_sure = 0,
  2017. X        save_em = FALSE;
  2018. X
  2019. X    file = ask_file((char *) 0, (char *) 0, filebuf);
  2020. X    if ((mac_fd = open(file, 0)) == -1)
  2021. X        complain(IOerr("open", file));
  2022. X
  2023. X    f_mess("\"%s\"", file);
  2024. X    while (read(mac_fd, (char *) &tmp, sizeof tmp) == (sizeof tmp)) {
  2025. Xretry:        bodylen = int_fmt(tmp);
  2026. X        if (!he_is_sure && (bodylen <= 0 || bodylen > 10000)) {
  2027. X            if (int_how == NEWWAY) {
  2028. X                int_how = OLDWAY;
  2029. X                save_em = TRUE;
  2030. X                goto retry;
  2031. X            } else {
  2032. X                confirm("Are you sure \"%s\" is a JOVE macro file? ", filebuf);
  2033. X                he_is_sure = 1;
  2034. X            }
  2035. X        }
  2036. X        nmacs++;
  2037. X        m = (struct macro *) emalloc (sizeof *m);
  2038. X        m->m_flags = 0;
  2039. X        m->m_len = bodylen;
  2040. X        m->m_buflen = m->m_len;
  2041. X        mac_io(read, (char *) &namelen, sizeof namelen);
  2042. X        namelen = int_fmt(namelen);
  2043. X        m->Name = emalloc(namelen);
  2044. X        mac_io(read, m->Name, namelen);
  2045. X        m->m_body = emalloc(m->m_buflen);
  2046. X        mac_io(read, m->m_body, m->m_len);
  2047. X        add_mac(m);
  2048. X    }
  2049. X    (void) close(mac_fd);
  2050. X    add_mess(" %d macro%n defined.", nmacs, nmacs);
  2051. X    if (save_em) {
  2052. X        char    *msg = "OK to convert to the new format? ",
  2053. X            ibuf[FILESIZE + 1];
  2054. X
  2055. X        if (!InJoverc) {
  2056. X            TOstart("Warning", TRUE);
  2057. X            Typeout("Warning: your macros file is in the old format.");
  2058. X            Typeout("Do you want me to convert \"%s\" to the new", pr_name(file));
  2059. X            Typeout("format?");
  2060. X            f_mess(msg);
  2061. X            TOstop();
  2062. X            confirm(msg);
  2063. X        }
  2064. X        /* WriteMacs requests a file name.  This is what it'll get. */
  2065. X        sprintf(ibuf, "%s\n", file);
  2066. X        Inputp = ibuf;
  2067. X        WriteMacs();
  2068. X    }        
  2069. X}
  2070. X
  2071. XRemember()
  2072. X{
  2073. X    if (KeyMacro.m_flags & EXECUTE)
  2074. X        /* We're already executing the macro; ignore any attempts
  2075. X           to define the keyboard macro while we are executing. */
  2076. X        return;
  2077. X    if (KeyMacro.m_flags & DEFINE)
  2078. X        message("[Already remembering ... continue with definition]");
  2079. X    else {
  2080. X        UpdModLine++;
  2081. X        KeyMacro.m_flags |= DEFINE;
  2082. X        MacNolen(&KeyMacro);
  2083. X        message("Remembering...");
  2084. X    }
  2085. X}
  2086. X
  2087. X/* Is `c' a prefix character */
  2088. X
  2089. Xprivate
  2090. XPrefChar(c)
  2091. X{
  2092. X    return (int) IsPrefix(mainmap[c]);
  2093. X}
  2094. X
  2095. XForget()
  2096. X{
  2097. X    char    *cp;
  2098. X    struct macro    *m = &KeyMacro;
  2099. X
  2100. X    UpdModLine++;
  2101. X    if (m->m_flags & DEFINE) {
  2102. X        message("Keyboard macro defined.");
  2103. X        m->m_flags &= ~DEFINE;
  2104. X        cp = &m->m_body[m->m_len - 2];
  2105. X        if (PrefChar(*cp))
  2106. X            m->m_len -= 2;
  2107. X        else if (commands[*++cp].c_proc == Forget)
  2108. X            m->m_len--;
  2109. X    }
  2110. X}
  2111. X
  2112. XExecMacro()
  2113. X{
  2114. X    do_macro(&KeyMacro);
  2115. X}
  2116. X
  2117. XMacInter()
  2118. X{
  2119. X    extern int    Interactive;
  2120. X
  2121. X    if (!Asking)
  2122. X        return;
  2123. X    Interactive = 1;
  2124. X}
  2125. X
  2126. XModMacs()
  2127. X{
  2128. X    register struct macro    *m;
  2129. X
  2130. X    for (m = macros->m_nextm; m != 0; m = m->m_nextm)
  2131. X        if (m->m_flags & SAVE)
  2132. X            return 1;
  2133. X    return 0;
  2134. X}
  2135. X
  2136. Xdata_obj *
  2137. Xfindmac(prompt)
  2138. Xchar    *prompt;
  2139. X{
  2140. X    char    *strings[100];
  2141. X    register char    **strs = strings;
  2142. X    register int    com;
  2143. X    register struct macro    *m = macros;
  2144. X
  2145. X    for (; m != 0; m = m->m_nextm)
  2146. X        *strs++ = m->Name;
  2147. X    *strs = 0;
  2148. X
  2149. X    if ((com = complete(strings, prompt, NOTHING)) < 0)
  2150. X        return 0;
  2151. X    m = macros;
  2152. X    while (--com >= 0)
  2153. X        m = m->m_nextm;
  2154. X    return (data_obj *) m;
  2155. X}
  2156. X
  2157. XDelMacro()
  2158. X{
  2159. X    struct macro    *m;
  2160. X
  2161. X    if ((m = (struct macro *) findmac(ProcFmt)) == 0)
  2162. X        return;
  2163. X    if (m == &KeyMacro)
  2164. X        complain("[It's illegal to delete the keyboard-macro!]");
  2165. X    del_mac(m);
  2166. X}
  2167. @//E*O*F macros.c//
  2168. if test 9026 -ne "`wc -c <'macros.c'`"; then
  2169.     echo shar: error transmitting "'macros.c'" '(should have been 9026 characters)'
  2170. fi
  2171. fi # end of overwriting check
  2172. echo shar: extracting "'malloc.c'" '(4003 characters)'
  2173. if test -f 'malloc.c' ; then 
  2174.   echo shar: will not over-write existing file "'malloc.c'"
  2175. else
  2176. sed 's/^X//' >malloc.c <<'@//E*O*F malloc.c//'
  2177. X/************************************************************************
  2178. X * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
  2179. X * provided to you without charge, and with no warranty.  You may give  *
  2180. X * away copies of JOVE, including sources, provided that this notice is *
  2181. X * included in all the files.                                           *
  2182. X ************************************************************************/
  2183. X
  2184. X#include "tune.h"
  2185. X
  2186. X#ifdef MY_MALLOC
  2187. X
  2188. X/*    avoid break bug */
  2189. X#ifdef pdp11
  2190. X#    define GRANULE 64
  2191. X#else
  2192. X#    define GRANULE 0
  2193. X#endif
  2194. X
  2195. X/*    C storage allocator
  2196. X *    circular first-fit strategy
  2197. X *    works with noncontiguous, but monotonically linked, arena
  2198. X *    each block is preceded by a ptr to the (pointer of) 
  2199. X *    the next following block
  2200. X *    blocks are exact number of words long 
  2201. X *    aligned to the data type requirements of ALIGN
  2202. X *    pointers to blocks must have BUSY bit 0
  2203. X *    bit in ptr is 1 for busy, 0 for idle
  2204. X *    gaps in arena are merely noted as busy blocks
  2205. X *    last block of arena (pointed to by alloct) is empty and
  2206. X *    has a pointer to first
  2207. X *    idle blocks are coalesced during space search
  2208. X *
  2209. X *    a different implementation may need to redefine
  2210. X *    ALIGN, NALIGN, BLOCK, BUSY, INT
  2211. X *    where INT is integer type to which a pointer can be cast
  2212. X */
  2213. X
  2214. X#define INT        int
  2215. X#define ALIGN        int
  2216. X#define NALIGN        1
  2217. X#define WORD        sizeof(union store)
  2218. X#define BLOCK        1024    /* a multiple of WORD*/
  2219. X#define BUSY        1
  2220. X#define NULL        0
  2221. X#define testbusy(p)    ((INT)(p)&BUSY)
  2222. X#define setbusy(p)    (union store *) ((INT) (p) | BUSY)
  2223. X#define clearbusy(p)    (union store *) ((INT) (p) &~ BUSY)
  2224. X
  2225. Xunion store {
  2226. X    union store    *ptr;
  2227. X    ALIGN    dummy[NALIGN];
  2228. X    int    calloc;        /*calloc clears an array of integers*/
  2229. X};
  2230. X
  2231. Xstatic union store    allocs[2],    /*initial arena*/
  2232. X            *allocp,    /*search ptr*/
  2233. X            *alloct,    /*arena top*/
  2234. X            *allocx;    /*for benefit of realloc*/
  2235. X
  2236. Xchar    *sbrk();
  2237. X
  2238. Xchar *
  2239. Xmalloc(nbytes)
  2240. Xunsigned int    nbytes;
  2241. X{
  2242. X    register union store    *p,
  2243. X                *q;
  2244. X    register int    nw;
  2245. X    static int    temp;    /* coroutines assume no auto */
  2246. X
  2247. X    if (allocs[0].ptr == 0) {    /* first time */
  2248. X        allocs[0].ptr = setbusy(&allocs[1]);
  2249. X        allocs[1].ptr = setbusy(&allocs[0]);
  2250. X        alloct = &allocs[1];
  2251. X        allocp = &allocs[0];
  2252. X    }
  2253. X    nw = (nbytes + WORD + WORD - 1) / WORD;
  2254. X    for (p = allocp; ; ) {
  2255. X        for (temp = 0; ; ) {
  2256. X            if (!testbusy(p->ptr)) {
  2257. X                while (!testbusy((q = p->ptr)->ptr))
  2258. X                    p->ptr = q->ptr;
  2259. X                if(q >= p + nw && p + nw >= p)
  2260. X                    goto found;
  2261. X            }
  2262. X            q = p;
  2263. X            p = clearbusy(p->ptr);
  2264. X            if (p > q)
  2265. X                ;
  2266. X            else if (q != alloct || p != allocs)
  2267. X                return NULL;
  2268. X            else if (++temp > 1)
  2269. X                break;
  2270. X        }
  2271. X        temp = ((nw + BLOCK/WORD) / (BLOCK/WORD)) * (BLOCK/WORD);
  2272. X        q = (union store *) sbrk(0);
  2273. X        if (q + temp + GRANULE < q)
  2274. X            return NULL;
  2275. X        q = (union store *) sbrk(temp * WORD);
  2276. X        if ((INT) q == -1)
  2277. X            return NULL;
  2278. X        alloct->ptr = q;
  2279. X        if (q != alloct+1)
  2280. X            alloct->ptr = setbusy(alloct->ptr);
  2281. X        alloct = q->ptr = q + temp - 1;
  2282. X        alloct->ptr = setbusy(allocs);
  2283. X    }
  2284. Xfound:
  2285. X    allocp = p + nw;
  2286. X    if (q > allocp) {
  2287. X        allocx = allocp->ptr;
  2288. X        allocp->ptr = p->ptr;
  2289. X    }
  2290. X    p->ptr = setbusy(allocp);
  2291. X    return (char *) (p + 1);
  2292. X}
  2293. X
  2294. X/* freeing strategy tuned for LIFO allocation */
  2295. X
  2296. Xfree(ap)
  2297. Xregister char    *ap;
  2298. X{
  2299. X    register union store    *p = (union store *) ap;
  2300. X
  2301. X    allocp = --p;
  2302. X    p->ptr = clearbusy(p->ptr);
  2303. X}
  2304. X
  2305. X/*    realloc(p, nbytes) reallocates a block obtained from malloc()
  2306. X *    and freed since last call of malloc()
  2307. X *    to have new size nbytes, and old content
  2308. X *    returns new location, or 0 on failure
  2309. X*/
  2310. X
  2311. Xchar *
  2312. Xrealloc(obj, nbytes)
  2313. Xchar    *obj;
  2314. Xunsigned int    nbytes;
  2315. X{
  2316. X    register union store    *q,
  2317. X                *p = (union store *) obj;
  2318. X    union store    *s,
  2319. X            *t;
  2320. X    register unsigned int    nw;
  2321. X    unsigned int    onw;
  2322. X
  2323. X    if (testbusy(p[-1].ptr))
  2324. X        free((char *) p);
  2325. X    onw = p[-1].ptr - p;
  2326. X    q = (union store *) malloc(nbytes);
  2327. X    if(q == NULL || q == p)
  2328. X        return((char *) q);
  2329. X    s = p;
  2330. X    t = q;
  2331. X    nw = (nbytes + WORD - 1)/WORD;
  2332. X    if (nw < onw)
  2333. X        onw = nw;
  2334. X    while (onw-- != 0)
  2335. X        *t++ = *s++;
  2336. X    if(q < p && q + nw >= p)
  2337. X        (q + (q+nw-p))->ptr = allocx;
  2338. X    return (char *) q;
  2339. X}
  2340. X
  2341. X#endif MY_MALLOC
  2342. @//E*O*F malloc.c//
  2343. if test 4003 -ne "`wc -c <'malloc.c'`"; then
  2344.     echo shar: error transmitting "'malloc.c'" '(should have been 4003 characters)'
  2345. fi
  2346. fi # end of overwriting check
  2347. echo shar: extracting "'marks.c'" '(4197 characters)'
  2348. if test -f 'marks.c' ; then 
  2349.   echo shar: will not over-write existing file "'marks.c'"
  2350. else
  2351. sed 's/^X//' >marks.c <<'@//E*O*F marks.c//'
  2352. X/************************************************************************
  2353. X * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
  2354. X * provided to you without charge, and with no warranty.  You may give  *
  2355. X * away copies of JOVE, including sources, provided that this notice is *
  2356. X * included in all the files.                                           *
  2357. X ************************************************************************/
  2358. X
  2359. Xint    MarksShouldFloat = 1;
  2360. X
  2361. X#include "jove.h"
  2362. X
  2363. XMark *
  2364. XMakeMark(line, column, type)
  2365. Xregister Line    *line;
  2366. X{
  2367. X    register Mark    *newmark = (Mark *) emalloc(sizeof *newmark);
  2368. X
  2369. X    MarkSet(newmark, line, column);
  2370. X    newmark->m_next = curbuf->b_marks;
  2371. X    newmark->m_floater = type;
  2372. X    curbuf->b_marks = newmark;
  2373. X    return newmark;
  2374. X}
  2375. X
  2376. XDelMark(m)
  2377. Xregister Mark    *m;
  2378. X{
  2379. X    register Mark    *mp = curbuf->b_marks;
  2380. X
  2381. X    if (m == mp)
  2382. X        curbuf->b_marks = m->m_next;
  2383. X    else {
  2384. X        while (mp != 0 && mp->m_next != m)
  2385. X            mp = mp->m_next;
  2386. X        if (mp == 0)
  2387. X            complain("Unknown mark!");
  2388. X        mp->m_next = m->m_next;
  2389. X    }
  2390. X    free((char *) m);
  2391. X}
  2392. X
  2393. XAllMarkSet(b, line, col)
  2394. XBuffer    *b;
  2395. Xregister Line    *line;
  2396. X{
  2397. X    register Mark    *mp;
  2398. X
  2399. X    for (mp = b->b_marks; mp != 0; mp = mp->m_next)
  2400. X        MarkSet(mp, line, col);
  2401. X}
  2402. X
  2403. XMarkSet(m, line, column)
  2404. XMark    *m;
  2405. XLine    *line;
  2406. X{
  2407. X    m->m_line = line;
  2408. X    m->m_char = column;
  2409. X}
  2410. X
  2411. XPopMark()
  2412. X{
  2413. X    int    pmark;
  2414. X
  2415. X    if (curmark == 0)
  2416. X        return;
  2417. X    if (curbuf->b_markring[(curbuf->b_themark + 1) % NMARKS] == 0) {
  2418. X        pmark = curbuf->b_themark;
  2419. X        do {
  2420. X            if (--pmark < 0)
  2421. X                pmark = NMARKS - 1;
  2422. X        } while (curbuf->b_markring[pmark] != 0);
  2423. X
  2424. X        curbuf->b_markring[pmark] = MakeMark(curline, curchar, MarksShouldFloat);
  2425. X        ToMark(curmark);
  2426. X        DelMark(curmark);
  2427. X        curmark = 0;
  2428. X    } else
  2429. X        PtToMark();
  2430. X
  2431. X    pmark = curbuf->b_themark - 1;
  2432. X    if (pmark < 0)
  2433. X        pmark = NMARKS - 1;
  2434. X    curbuf->b_themark = pmark;
  2435. X}
  2436. X
  2437. XSetMark()
  2438. X{
  2439. X    if (exp_p)
  2440. X        PopMark();
  2441. X    else
  2442. X        DoSetMark(curline, curchar);
  2443. X}
  2444. X
  2445. XDoSetMark(l, c)
  2446. XLine    *l;
  2447. X{
  2448. X    curbuf->b_themark = (curbuf->b_themark + 1) % NMARKS;
  2449. X    if (curmark == 0)
  2450. X        curmark = MakeMark(l, c, MarksShouldFloat);
  2451. X    else
  2452. X        MarkSet(curmark, l, c);
  2453. X    s_mess("[Point pushed]");
  2454. X}
  2455. X
  2456. X/* Move point to Mark */
  2457. X
  2458. XToMark(m)
  2459. XMark    *m;
  2460. X{
  2461. X    int    len;
  2462. X
  2463. X    if (m == 0)
  2464. X        return;
  2465. X    DotTo(m->m_line, m->m_char);
  2466. X    if (curchar > (len = length(curline)))
  2467. X        curchar = len;
  2468. X}
  2469. X
  2470. XMark *
  2471. XCurMark()
  2472. X{
  2473. X    if (curmark == 0)
  2474. X        complain("No mark.");
  2475. X    return curmark;
  2476. X}
  2477. X
  2478. XPtToMark()
  2479. X{
  2480. X    Line    *mline;
  2481. X    int    mchar;
  2482. X    Mark    *m = CurMark();
  2483. X
  2484. X    mline = curline;
  2485. X    mchar = curchar;
  2486. X
  2487. X    ToMark(m);
  2488. X    MarkSet(m, mline, mchar);
  2489. X}
  2490. X
  2491. X/* Fix marks for after a deletion.  For now, even marks that don't
  2492. X   float will actually float, because we can't allow marks to point
  2493. X   to non-existant lines. */
  2494. X
  2495. XDFixMarks(line1, char1, line2, char2)
  2496. Xregister Line    *line1,
  2497. X        *line2;
  2498. X{
  2499. X    register Mark    *m;
  2500. X    Line    *lp = line1;
  2501. X
  2502. X    if (curbuf->b_marks == 0)
  2503. X        return;
  2504. X    while (lp != line2->l_next) {
  2505. X        for (m = curbuf->b_marks; m != 0; m = m->m_next) {
  2506. X/*            if (!m->m_floater)
  2507. X                continue; */
  2508. X            if (m->m_line == lp)
  2509. X                m->m_char |= (1 << 15);
  2510. X        }
  2511. X        lp = lp->l_next;
  2512. X    }
  2513. X    for (m = curbuf->b_marks; m; m = m->m_next) {
  2514. X/*        if (!m->m_floater)
  2515. X            continue; */
  2516. X        if ((m->m_char & (1 << 15)) == 0)
  2517. X            continue;    /* Not effected */
  2518. X        m->m_char &= ~(1 << 15);
  2519. X        if (m->m_line == line1 && m->m_char < char1)
  2520. X            continue;    /* This mark is not affected */
  2521. X        if (line1 == line2) {
  2522. X            if (m->m_char >= char1 && m->m_char <= char2)
  2523. X                m->m_char = char1;
  2524. X            else if (m->m_char > char2)
  2525. X                m->m_char -= (char2 - char1);
  2526. X            /* Same line move the mark backward */
  2527. X        } else if (m->m_line == line2) {
  2528. X            if (m->m_char > char2)
  2529. X                m->m_char = char1 + (m->m_char - char2);
  2530. X            else
  2531. X                m->m_char = char1;
  2532. X            m->m_line = line1;
  2533. X        } else {
  2534. X            m->m_char = char1;
  2535. X            m->m_line = line1;
  2536. X        }
  2537. X    }
  2538. X}
  2539. X
  2540. X/* Fix marks after an insertion.  Marks that don't float are ignored
  2541. X   on insertion, which means PtToMark has to be careful ... */
  2542. X
  2543. XIFixMarks(line1, char1, line2, char2)
  2544. Xregister Line    *line1,
  2545. X        *line2;
  2546. X{
  2547. X    register Mark    *m;
  2548. X
  2549. X    for (m = curbuf->b_marks; m != 0; m = m->m_next) {
  2550. X        if (!m->m_floater)
  2551. X            continue;
  2552. X        if (m->m_line == line1) {
  2553. X            if (m->m_char > char1) {
  2554. X                m->m_line = line2;
  2555. X                if (line1 == line2)
  2556. X                    m->m_char += (char2 - char1);
  2557. X                else
  2558. X                    m->m_char = char2 + (m->m_char - char1);
  2559. X            }
  2560. X        } 
  2561. X    }
  2562. X}
  2563. @//E*O*F marks.c//
  2564. if test 4197 -ne "`wc -c <'marks.c'`"; then
  2565.     echo shar: error transmitting "'marks.c'" '(should have been 4197 characters)'
  2566. fi
  2567. fi # end of overwriting check
  2568. echo shar: extracting "'setmaps.c'" '(2200 characters)'
  2569. if test -f 'setmaps.c' ; then 
  2570.   echo shar: will not over-write existing file "'setmaps.c'"
  2571. else
  2572. sed 's/^X//' >setmaps.c <<'@//E*O*F setmaps.c//'
  2573. X/************************************************************************
  2574. X * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
  2575. X * provided to you without charge, and with no warranty.  You may give  *
  2576. X * away copies of JOVE, including sources, provided that this notice is *
  2577. X * included in all the files.                                           *
  2578. X ************************************************************************/
  2579. X
  2580. X#define TXT_TO_C
  2581. X
  2582. X#include "funcdefs.c"
  2583. X#undef putchar    /* From jove.h via funcdefs.c, conflicts with STDIO */
  2584. X#undef putc
  2585. X#undef getc
  2586. X#undef EOF
  2587. X#undef FILE
  2588. X#undef BUFSIZ
  2589. X#include <stdio.h>
  2590. X
  2591. Xmatch(choices, what)
  2592. Xregister struct cmd    choices[];
  2593. Xregister char    *what;
  2594. X{
  2595. X    register int    len;
  2596. X    int    i,
  2597. X        found = 0,
  2598. X        save,
  2599. X        exactmatch = -1;
  2600. X
  2601. X    len = strlen(what);
  2602. X    for (i = 0; choices[i].Name != 0; i++) {
  2603. X        if (*what != *choices[i].Name)
  2604. X            continue;
  2605. X        if (strncmp(what, choices[i].Name, len) == 0)
  2606. X            return i;
  2607. X    }
  2608. X    return -1;
  2609. X}
  2610. X
  2611. Xchar *
  2612. XPPchar(c)
  2613. Xint    c;
  2614. X{
  2615. X    static char    str[10];
  2616. X    char    *cp = str;
  2617. X
  2618. X    if (c == '\033')
  2619. X        strcpy(cp, "ESC");
  2620. X    else if (c < ' ')
  2621. X        (void) sprintf(cp, "C-%c", c + '@');
  2622. X    else if (c == '\177')
  2623. X        strcpy(cp, "^?");
  2624. X    else
  2625. X        (void) sprintf(cp, "%c", c);
  2626. X    return cp;
  2627. X}
  2628. X
  2629. Xextract(into, from)
  2630. Xchar    *into,
  2631. X    *from;
  2632. X{
  2633. X    from += 2;    /* Past tab and first double quote. */
  2634. X    while ((*into = *from++) != '"')
  2635. X        into++;
  2636. X    *into = 0;
  2637. X}
  2638. X
  2639. Xmain()
  2640. X{
  2641. X    FILE    *ifile,
  2642. X        *of;
  2643. X    char    line[100],
  2644. X        comname[70];
  2645. X    int    comnum,
  2646. X        ch;
  2647. X
  2648. X    ifile = stdin;
  2649. X    of = stdout;
  2650. X    if (ifile == NULL || of == NULL) {
  2651. X        printf("Cannot read input or write output.\n");
  2652. X        exit(1);
  2653. X    }
  2654. X    while (fgets(line, sizeof line, ifile) != NULL) {
  2655. X        if (strncmp(line, "\t\"", 2) != 0) {
  2656. X            fprintf(of, line);
  2657. X            ch = 0;
  2658. X            continue;
  2659. X        }
  2660. X        extract(comname, line);
  2661. X        if (strcmp(comname, "unbound") == 0) 
  2662. X            comnum = 12345;
  2663. X        else {
  2664. X            comnum = match(commands, comname);
  2665. X            if (comnum < 0) {
  2666. X                fprintf(stderr, "Cannot find command \"%s\".\n", comname);
  2667. X                exit(1);
  2668. X            }
  2669. X        }
  2670. X        if (comnum == 12345)
  2671. X            fprintf(of, "    (data_obj *) 0,                 /* %s */\n", PPchar(ch++));
  2672. X        else
  2673. X            fprintf(of, "    (data_obj *) &commands[%d],    /* %s */\n", comnum, PPchar(ch++));
  2674. X    }
  2675. X    fclose(of);
  2676. X    fclose(ifile);
  2677. X    exit(0);
  2678. X}
  2679. @//E*O*F setmaps.c//
  2680. if test 2200 -ne "`wc -c <'setmaps.c'`"; then
  2681.     echo shar: error transmitting "'setmaps.c'" '(should have been 2200 characters)'
  2682. fi
  2683. fi # end of overwriting check
  2684. echo shar: "End of archive 5 (of 13)."
  2685. cp /dev/null ark5isdone
  2686. DONE=true
  2687. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13; do
  2688.     if test -f ark${I}isdone; then
  2689.         echo "You have run archive ${I}."
  2690.     else
  2691.         echo "You still need to run archive ${I}."
  2692.         DONE=false
  2693.     fi
  2694. done
  2695. case $DONE in
  2696.     true)
  2697.         echo "You have run all 13 archives."
  2698.         echo 'Now read the README and Makefile.'
  2699.         ;;
  2700. esac
  2701. ##  End of shell archive.
  2702. exit 0
  2703.